【发布时间】:2011-03-06 21:38:10
【问题描述】:
我正在尝试制作一个像样的 Java 程序,它可以生成从 1 到 N 的素数(主要用于 Project Euler 问题)。
目前我的算法如下:
初始化一个布尔数组(如果 N 足够大,则初始化一个位数组)以使它们全部为假,并初始化一个整数数组来存储找到的素数。
设置一个整数,s等于最低素数,(即2)
虽然 s 是
在数组/位数组中将 s 的所有倍数(从 s^2 开始)设置为 true。
在数组/位数组中找到下一个为假的最小索引,将其用作 s 的新值。
结束。
遍历数组/位数组,对于每个为假的值,将相应的索引放入素数数组中。
现在,我尝试跳过不是 6k + 1 或 6k + 5 形式的数字,但这只会让我的速度提高约 2 倍,而我看到程序的运行速度比我的快几个数量级(尽管非常复杂的代码),例如here
我可以做些什么来改进?
编辑:好的,这是我的实际代码(N of 1E7):
int l = 10000000, n = 2, sqrt = (int) Math.sqrt(l);
boolean[] nums = new boolean[l + 1];
int[] primes = new int[664579];
while(n <= sqrt){
for(int i = 2 * n; i <= l; nums[i] = true, i += n);
for(n++; nums[n]; n++);
}
for(int i = 2, k = 0; i < nums.length; i++) if(!nums[i]) primes[k++] = i;
在我的 2.0GHz 机器上运行大约 350 毫秒。
【问题讨论】:
-
虽然 java 不是这里最快的选择,但如果您发布(完整但紧凑的)代码,我们可能会发现性能问题。
-
顺便说一下,实施埃拉托色尼筛法一点也不复杂:)