我遇到了我的Eratosthenes筛子的问题。我想编写一个Sieve,它不需要所有数字的数组,直到你想要的最大素数,而只是跟踪Sieve到达它时的每个素数。这意味着您不必预先完成所有工作,但可以在需要时确定下一个素数。添加界面功能也很容易,例如“从N开始查找K素数”。这是伪代码:
Begin with current number set to 2
Loop:
If prime queue is not empty:
Peek at the top prime in the queue
If current > top, we can move top to the next multiple
Remove the top prime from the prime queue
Increment top to its next multiple
Re-add it to the queue
If current == top, current is not a prime
Increment current number to next integer
If current < top, we've found a prime
Break
Push current number onto prime queue
Increment current number to next integer
Return the new prime
所以这就是问题所在:我正确地计算了前31个素数(最多127个),但之后认为每个数是素数。我把我的代码放在Ideone上 - 我希望它是一些Java集合行为,或者是一个简单的bug,而不是算法本身。我想不出算法在一定数量的素数之后应该破裂的原因。我已经手动确认在127之后,如果堆正确排序,我的算法应该识别128不是素数,但这不是代码给我看的。
有什么建议吗?
(当然,一旦我使基本算法工作,我将增加2(跳过所有非素数偶数)。我可能也会使Sieve成为可迭代的。)
答案 0 :(得分:4)
你的问题是
top.multiple == current
与
有关Integer current = 2;
Integer multiple;
如果我没记错的话,有一个Integer
的缓存,其绝对值很小,-128
到127
,因此使用==
的比较会比较值的相同实例小于128.但从128开始,您为Integer
获得了一个新的框current
,这是与top.multiple
引用的对象不同的对象。
使用equals
进行比较或声明int current;
来解决它。
并改进你的算法,只注意每个素数的倍数从素数的平方。
答案 1 :(得分:1)
你没有检查整个清单:
31之后的Sieve堆: [[127:127],[11:132],[2:128]
你到了132,这是&gt; 128,因此在检查2 * 64之前点击break;
。