【发布时间】:2015-05-23 09:57:03
【问题描述】:
要生成最多 N i 的 Prime 是使用此代码。
private static void primePrint(int n) {
int sum=0;
int maxFactor= (int)Math.sqrt(n);
boolean[] isPrime=new boolean[n + 1];
int len=isPrime.length;
Arrays.fill(isPrime,true);
isPrime[0]=false;
isPrime[1]=false;
for(int i=0;i<=maxFactor;i++){
if(isPrime[i]){
for(int j=i+i;j<len;j+=i){
isPrime[j]=false;
}
}
}
for(int i=2;i<=n;i++){
if(isPrime[i]){
System.out.println(i)
}
}
}
但最近有人建议我将 maxfactor 减半并使用此循环,因为它可以提高效率。但我无法了解它是如何运作的。
maxFactor = maxFactor/2 - 1;
boolean[] isPrime = new boolean[n/2+1];
for(int i = 0; i < maxFactor; ++i) {
if (!isPrime[i]) {
for(int j = 2*i*(i+3)+3, p = 2*i+3; j < n/2; j += p) {
isPrime[j] = true;
}
如果有人能对此有所了解,那将有很大帮助。
编辑:使用此生成 nthPrime 的工作代码
class Ideone
{
public static void main (String[] args) throws java.lang.Exception
{
System.out.println(nthPrime(25));
}
public static int nthPrime(int n) {
if (n < 2) return 2;
if (n == 2) return 3;
int limit, root, count = 1;
limit = (int)(n*(Math.log(n) + Math.log(Math.log(n)))) + 3;
root = (int)Math.sqrt(limit) + 1;
limit = (limit-1)/2;
root = root/2 - 1;
boolean[] sieve = new boolean[limit];
for(int i = 0; i < root; ++i) {
if (!sieve[i]) {
++count;
for(int j = 2*i*(i+3)+3, p = 2*i+3; j < limit; j += p) {
sieve[j] = true;
}
}
}
int p;
for(p = root; count < n; ++p) {
if (!sieve[p]) {
++count;
}
}
return 2*p+1;
}
}
【问题讨论】:
-
您在寻找特定类型的素数吗?
-
我无法通过减少检查的次数甚至是根的一半然后检查直到 n/2 才知道如何生成直到 n 的所有素数。以及
j = 2*i*(i+3)+3, p = 2*i+3实际在做什么。 -
这是埃拉托色尼筛的标准优化;它只筛选奇数,因为除 2 之外的所有偶数都是合数。请参阅 my blog 上对 j 公式的解释和推导。
标签: java performance primes