您的位置:首页 > 编程语言 > Java开发

素数计算---改良版埃氏筛选和欧拉筛选

2016-07-11 16:16 441 查看
埃氏筛选:

例如要找不超过100的所有素数。

需要建立一个大小为100加1个的布尔数组,称为isPrime。

已知0和1不是素数,所以,先找到第一个素数2,那么将其标记为素数。

isPrime[2] = true;

那么2的倍数肯定不是素数,使用建立的布尔数组对它们进行标记

isPrime[2*2] = false;

isPrimer[2*3] = false;

isPrimer[2*n] = false;

当2*n>100时,停止标记。

找第二个素数B,素数B的倍数肯定也不是素数,同样对它们进行标记。

缺陷很明显,会对一些数重复进行标记。

如2和5都是素数,2和5的倍数都有10,20,30,40,50

这些都会重复标记,造成了极大的浪费。

所以有了以下的改良方法,照搬曾加的。

/**
* Created by xu-cat on 2016/7/11.
* 使用筛选法,计算出N个以内的素数
* 作者:曾加
* 链接:https://www.zhihu.com/question/24942373/answer/29599552
*/
class Prime{
public static int calculateNumber(int Nmax){
boolean[] isPrime=new boolean[Nmax+1];
//假定所有奇数为素数,即首先筛掉偶数
for(int i=3;i<=Nmax;i+=2)
isPrime[i]=true;
isPrime[2]=true;
for(int i=3;i<=Math.sqrt(Nmax);i+=2){
if(isPrime[i]==true){
// 偶数是不需要判断的
// j+=2*i中i必定是奇数,那么i*2之后必定是偶数
// 奇数+偶数=奇数,所以j一直是奇数,从而排除了标记偶数
for(int j=i*i;j<=Nmax;j+=2*i)
isPrime[j]=false;
}
}
int primeNum=0;
for(int i=1;i<=Nmax;i++){
if(isPrime[i]==true) {
primeNum++;
}
}
return primeNum;
}
public static int calculateNumber1(int Nmax) {
boolean[] isPrime = new boolean[Nmax + 1];
//存着素数
int[] prime = new int[Nmax / 10];
//筛选偶数,只留下奇数
for (int i = 3; i <= Nmax; i += 2)
isPrime[i] = true;
//2先处理掉
isPrime[2] = true;
prime[0] = 2;
int totalPrimes = 1;

for (int i = 3; i <= Nmax; i += 2) {
if (isPrime[i])
prime[totalPrimes++] = i;

for (int j = 1; i * prime[j] <= Nmax && j < totalPrimes; j++){
isPrime[i * prime[j]] = false;
//看不懂,先放着,再见!
if(i % prime[j] == 0)
break;
}
}
return totalPrimes;
}
public static void main(String[] args){
ooxx(20000000, true);
ooxx(20000000, false);
}
public static void ooxx(int Nmax, boolean choose) {
double startTime=System.currentTimeMillis();
int primeNum;
if (choose) {
//改良版埃氏筛法
primeNum=Prime.calculateNumber(Nmax);
} else {
//选择欧拉晒法
primeNum=Prime.calculateNumber1(Nmax);
}
double timeSpent=(System.currentTimeMillis()-startTime)/1000;
System.out.println("The prime numbers from 1 to "+Nmax+" is "+primeNum);
System.out.println("Time spent : "+timeSpent+" s");
}
}


改良版
Time spent : 0.294 s
欧拉版
Time spent : 0.29 s


END

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  素数 JAVA