我有两个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)),但我不确定。我不确定第二种增长率是多少。
答案 0 :(得分:4)
第二个更有效率。它也是Eratosthenes的筛子。第一种算法是试验分割,并且不是 Eratosthenes的筛子。
第一种算法的时间复杂度为O( n sqrt( n )),如果仅使用素数作为试验除数,则可能会少一些。第二种算法的时间复杂度为O( n log log n ),因为log log n 非常小,所以它足够线性
作为一项实验,计算第一百万个素数,最多为15485863,并查看哪一个更快。它甚至不会接近。第二种算法将在几秒钟内完成。第一种算法需要几个小时。