我正在尝试编写一个可以生成从1到N的质数(主要用于欧拉计划问题)的Java程序。
目前,我的算法如下:
初始化一个布尔数组(如果N足够大,则使用位数组),使它们都为false,并初始化一个存储找到的质数的int数组。
设置一个整数s等于最小的质数(即2)。
当s <= sqrt(N)时,
在数组/位数组中将s的所有倍数(从s ^ 2开始)设置为true。
找到数组/位数组中下一个最小的值为false的索引,将其用作新的s值。
重复此过程直至结束。
遍历数组/位数组,并将每个为false的值对应的索引放入质数数组中。
现在,我已经尝试跳过非6k + 1或6k + 5形式的数字,但这只使我的速度提高了约两倍,而我已经看到比我的程序运行速度快数个数量级(虽然代码非常复杂),例如此处的程序。
我应该怎么改进呢?
编辑:好吧,这是我的实际代码(用于1E7的N):
目前,我的算法如下:
初始化一个布尔数组(如果N足够大,则使用位数组),使它们都为false,并初始化一个存储找到的质数的int数组。
设置一个整数s等于最小的质数(即2)。
当s <= sqrt(N)时,
在数组/位数组中将s的所有倍数(从s ^ 2开始)设置为true。
找到数组/位数组中下一个最小的值为false的索引,将其用作新的s值。
重复此过程直至结束。
遍历数组/位数组,并将每个为false的值对应的索引放入质数数组中。
现在,我已经尝试跳过非6k + 1或6k + 5形式的数字,但这只使我的速度提高了约两倍,而我已经看到比我的程序运行速度快数个数量级(虽然代码非常复杂),例如此处的程序。
我应该怎么改进呢?
编辑:好吧,这是我的实际代码(用于1E7的N):
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毫秒。