【一线大厂Java面试题解析+后端开发学习笔记+最新架构讲解视频+实战项目源码讲义】
**开源地址:https://docs.qq.com/doc/DSmxTbFJ1cmN1R2dB **
2.优化算法
private static int findZhiShu(int num) {
int counts = 0;
if (num < 2) {
return counts;
}
for (int i = 2; i <= num; i++) {
boolean isZhiShu = true;
double index=Math.sqrt(i);
for (int j = 2; j <=index; j++) {
if (i % j == 0) {
isZhiShu = false;
break;
}
}
if (isZhiShu) {
System.out.print(i + " ");//输出质数
counts++;
}
}
return counts;
}
这里用到了 取平方的方法,缩小了查找的范围,原因如下:
循环到sqrt(N)即可,简单解释一下:因数都是成对出现的。比如,100的因数有:1和100,
2和50,4和25,5和20,10和10。看出来没有?成对的因数,其中一个必然小于等于100的开平方,另一个大于等于100的开平方。
这个方法只能在百万级以下的数时,在3秒以内。
3.进一步优化的算法
private static int findZhiShu(int n){
boolean[] primes= filterNumber(n);
int num=0;
if(primes!=null){
for(int i=1;i<primes.length;i++){
if(primes[i]){
// System.out.print(i+" "); //打印质数
num++;
}
}
}
// System.out.println("一共有"+num+"个质数");
return num;
}
//筛选法
private static boolean[] filterNumber(int num){
if(num<=0){
System.out.println("范围必须大于0");
return null;
}
boolean[] isPrime = new boolean[num + 1];
isPrime[1] = false;
Arrays.fill(isPrime,2,num,true);
int n = (int)Math.sqrt(num);
for(int i=1;i<=n;i++){
if(isPrime[i]){
for(int j=i*i;j<=num;j+=i){ //2*i改为i*i可以避免重复赋值,效率提升了约6%
isPrime[j]= false;
}
}
}
return isPrime;
}
用到的是 筛选法。依次剔除2的倍数,3的倍数,5的倍数…
这个算法可以有效的对付9位数(上亿),我计算机测试输入123456789时,花费时间在3秒以内,在计算大数时,效率大约是第二种的80-100倍左右.
毫无疑问,必须得选第三种方法。
参考代码如下:
import java.util.Arrays;
import java.util.Scanner;
public class Test0 {
public static void main(String[] args) {
Scanner mScanner = new Scanner(System.in);
int len = mScanner.nextInt();
int counts = 0;
int array[] = new int[len];
for (int i = 0; i < len; i++) {
array[i] = mScanner.nextInt();
}
// long time0=System.currentTimeMillis();
for (int i = 0; i < len-1; i++) {
for (int j = i+1; j < len; j++) {
counts += findZhiShu(array[j])-findZhiShu(array[i]);
}
}
// long time1=System.currentTimeMillis();
System.out.println(counts);
// System.out.println((double)(time1-time0)/1000);
}
//筛选法
private static boolean[] filterNumber(int num){
if(num<=0){
System.out.println("范围必须大于0");
return null;
}
boolean[] isPrime = new boolean[num + 1];
isPrime[1] = false;
Arrays.fill(isPrime,2,num,true);
int n = (int)Math.sqrt(num);
for(int i=1;i<=n;i++){
if(isPrime[i]){
for(int j=i*i;j<=num;j+=i){ //2*i改为i*i可以避免重复赋值,效率提升了约6%
isPrime[j]= false;
}
}
}
return isPrime;
}
private static int findZhiShu(int n){
boolean[] primes= filterNumber(n);
int num=0;
if(primes!=null){
for(int i=1;i<primes.length;i++){