哪个Sierat of Eratosthenes实施效率更高?

时间:2015-03-09 19:09:10

标签: java algorithm big-o

我有两个Eratosthenes筛子的实施。这是第一个:

public class SieveOfEratosthenes extends PrimeGenerator {

    private boolean[] sieve;
    private List<Integer> primes;

    public SieveOfEratosthenes(int depth) {
        super(depth);

        sieve = new boolean[depth + 1];
        primes = new ArrayList<>();

        generate();
    }

    private void setPrime(int n) {
        sieve[n] = true;
        primes.add(n);
    }

    private void generate() {
        setPrime(2);
        setPrime(3);

        for (int n = 4; n <= depth; n++) {
            boolean isPrime = true;

            for (int prime : primes) 
                if (n % prime == 0) 
                    isPrime = false;

            if (isPrime)
                setPrime(n);
        }
    }
}

这是第二个。

public boolean[] sieve(int n)
{
   boolean[] prime=new boolean[n+1];
   Arrays.fill(prime,true);
   prime[0]=false;
   prime[1]=false;
   int m=Math.sqrt(n);

   for (int i=2; i<=m; i++)
      if (prime[i])
         for (int k=i*i; k<=n; k+=i)
            prime[k]=false;

   return prime;
} 

显然第二种不那么冗长。它并不意味着成为主要生成者层次结构的一部分。但我的问题是,哪个更有效率?第一个似乎是O(N * log(N)),但我不确定。我不确定第二种增长率是多少。

1 个答案:

答案 0 :(得分:4)

第二个更有效率。它也是Eratosthenes的筛子。第一种算法是试验分割,并且不是 Eratosthenes的筛子。

第一种算法的时间复杂度为O( n sqrt( n )),如果仅使用素数作为试验除数,则可能会少一些。第二种算法的时间复杂度为O( n log log n ),因为log log n 非常小,所以它足够线性

作为一项实验,计算第一百万个素数,最多为15485863,并查看哪一个更快。它甚至不会接近。第二种算法将在几秒钟内完成。第一种算法需要几个小时。