【发布时间】:2016-03-31 01:35:46
【问题描述】:
我正在研究一种在 Java 中创建布尔数组 isPrime 的方法:
boolean[] isPrime;
其中素数标记为“真”,其余标记为“假”。
在此过程中,我还想计算找到的 Prime 数量:
int numPrimesFound;
基本思想是使用埃拉托色尼筛。到目前为止,我的方法如下所示:
public Sieve(final int limit) {
long startTime = System.currentTimeMillis();
boolean[] isPrime = new boolean[limit];
this.isPrime = isPrime;
for (int i=3; i<=limit ;i+=2) {
isPrime[i] = true; //sets all even numbers to true
}
isPrime[2] = true;
numPrimesFound = 1; //special case of '2'
for (int i = 3; i * i <= limit; i += 2) {
if (isPrime[i] == true) {
for (int j = i; i * j <= limit; j += 2) {
isPrime[i * j] = false; //has a multiple ==> not a prime
numPrimesFound++; //doesn't work yet
}
}
}
long stopTime = System.currentTimeMillis(); //measuring execution time
System.out.println("Sieve: " + (stopTime - startTime) + " milliseconds.")
}
所以我的问题是
numPrimesFound++:
不起作用,因为筛子将一些非素数的值设置为“假”不止一次(例如 45 bcs 3*15 = 45 和 9*5 = 45)。
那么有没有人知道我可以如何重写这个程序,以便将所有非质数设置为“假”只有一次?
或者一般来说,任何人都可以提出使该方法更快的方法吗?
【问题讨论】:
-
您对哪个结果感兴趣:素数计数,还是素数本身?如您所见,
numPrimesFound是错误的,但这与算法查找素数的速度无关。另外:您可能应该阅读How to write a correct microbenchmark in Java。 -
去掉内部循环中的乘法,只留下加法:
i*(j + 2) == i*j + 2*i。
标签: java primes sieve-of-eratosthenes sieve