Eratosthenes的Sieve认为在127之后所有数字都是素数

时间:2012-04-02 20:04:51

标签: java algorithm primes sieve-of-eratosthenes

我遇到了我的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不是素数,但这不是代码给我看的。

有什么建议吗?

http://ideone.com/E07Te

(当然,一旦我使基本算法工作,我将增加2(跳过所有非素数偶数)。我可能也会使Sieve成为可迭代的。)

2 个答案:

答案 0 :(得分:4)

你的问题是

top.multiple == current

有关
Integer current = 2;
Integer multiple;

如果我没记错的话,有一个Integer的缓存,其绝对值很小,-128127,因此使用==的比较会比较值的相同实例小于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;