实际上,只需 2 个就足够了。硬编码 3 最多可以节省一毫秒。没有必要在 1 上竖琴。我相信包括它是一个诚实的错误。你已经知道了,并且在这个程序上工作将有助于证实这一点。
最后一个数字?在什么基地?基数 10?我想这可能是你的问题。
- 检查数字是否为 0、2 或 4 或 6 或 8,然后跳过数字,否则计算数字的平方根
我认为这就是问题所在。您的程序应该简单地跳过偶数,因为除了 -2 和 2 之外,它们都是复合的。另一方面,这不会将运行时间减半,因为像 91 和 2209 这样的奇数可能需要更多的努力才能被排除为非质数。
- 尝试将数字从 2 开始除以数字的平方根,如果数字是可整除的,则跳过数字,否则将其添加到素数列表
“2 直到数字的平方根”是否包括像 4、6 和 9 这样的数字?唯一需要检查的潜在因素是已经被证明是素数的数字。如果n不能被 7 整除,则它也不能被 49 整除。如果你正在建立一个列表,你不妨用它来检查潜在的素数。
对 Java 进行基准测试有点困难,因为您受制于运行时系统。尽管如此,一分半钟虽然被梅森认为是奇迹,但在今天还是太慢了。五,十秒,我觉得可以接受。
也许这是您应该避免使用对象来支持原语数组的情况之一。我的初稿比你的还要长。最终我想出了这个:
static int[] fillWithPrimes(int quantity) {
int[] primes = new int[quantity];
primes[0] = 2;
int currPi = 1;
int currIndex = 0;
int currNum = 3;
int currPrime;
boolean coPrimeFlag;
double squareRoot;
while (currPi < quantity) {
squareRoot = Math.sqrt(currNum);
do {
currPrime = primes[currIndex];
coPrimeFlag = (currNum % currPrime != 0);
currIndex++;
} while (coPrimeFlag && currPrime <= squareRoot);
if (coPrimeFlag) {
primes[currPi] = currNum;
currPi++;
}
currNum += 2;
currIndex = 0;
}
return primes;
}
然后我写了一个main()
记录调用前的时间,fillWithPrimes()
参数quantity
为 1,000,000,并报告结果:
跑:
操作耗时 2378 毫秒
第 10 个素数是 29
第 100 个素数是 541
第 1000 个素数是 7919
第 10000 个素数是 104729
第 100000 个素数是 1299709
第 1000000 个素数是 15485863
构建成功(总时间:2 秒)
我相信它可以进一步优化。就我个人而言,我对两秒半的时间感到满意。