使用Eratosthenes筛子的Prime Generation具有更好的性能

时间:2015-05-23 09:57:04

标签: java performance primes

要生成Prime到N,我正在使用此代码。

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;
}
}

IDEONE LINK

2 个答案:

答案 0 :(得分:1)

  

但是最近有人建议我将我的maxfactor减半并使用这个循环,因为它会提高效率。

我怀疑那个&#34;某人&#34;是错的。 (也许他们在戏弄你......)

maxFactor == sqrt(N)背后的原因是:

  • 筛子删除非素数
  • 如果X是非素数,那么它必须至少有两个素因子。
  • 如果X小于N,则其至少一个素因子必须小于或等于sqrt(N)

但是,如果使maxFactor小于sqrt(N),则可能不会删除一个或多个非素数。换句话说,你在筛子上打了一个洞。

你修改过的版本中的内循环对我来说毫无意义......作为Eratosthenes筛选的实现。

事实上,根据您提供的链接中的代码,我认为这是Sieve of Sundaram(而不是您标记的Eratosthenes的Sieve。)我还会注意到该链接的代码正在解决一个不同的问题:找到第N个素数(并非所有质数都小于或等于N)。

无论如何,我的回答是,作为你关于实施Eratosthenes筛选的问题的答案。

(如果你想要解决Sundaram的筛子......你已经拥有它了。)

答案 1 :(得分:0)

我认为你不能让这项工作产生素数。为了证明你的朋友没有找到一个很好的新方法来生成素数我提交:     j = 2 * i *(i + 3)+3 是什么分配素数但是当你到达i = 1然后j = 11并且我们还没有指定5作为素数。由于我认为算法无法返回,我们错过了一个素数。

同样isPrime被初始化为n / 2 + 1大小,所以我们甚至没有空间来收集我们正在寻找的数据。