Java 埃拉托什尼筛认为所有数字都是127之后的素数
我的埃拉托什尼筛出了问题。我想写一个筛子,它不需要所有数字的数组,直到你想要的最大素数,而只是在筛子到达时跟踪每个素数的倍数。这意味着你不必预先做所有的工作,只需在需要时确定下一个素数即可。添加诸如“查找从N开始的K素数”之类的接口特性也很容易。以下是伪代码:Java 埃拉托什尼筛认为所有数字都是127之后的素数,java,algorithm,primes,sieve-of-eratosthenes,Java,Algorithm,Primes,Sieve Of Eratosthenes,我的埃拉托什尼筛出了问题。我想写一个筛子,它不需要所有数字的数组,直到你想要的最大素数,而只是在筛子到达时跟踪每个素数的倍数。这意味着你不必预先做所有的工作,只需在需要时确定下一个素数即可。添加诸如“查找从N开始的K素数”之类的接口特性也很容易。以下是伪代码: Begin with current number set to 2 Loop: If prime queue is not empty: Peek at the top prime in the queue
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
以设置为2的当前数字开始
循环:
如果主队列不为空:
窥视队列中的最高质数
如果当前>顶部,我们可以将顶部移动到下一个多个位置
从主队列中删除顶级主队列
将top递增到下一个倍数
重新将其添加到队列中
如果current==top,则current不是素数
将当前数字增加到下一个整数
如果current
问题是:我正确地计算了前31个素数(最多127个),但之后它认为每个数字都是素数。我把代码放在了Ideone上——我希望这是一些Java集合行为,或者是一个小错误,而不是算法本身。我想不出一个原因,在一定数量的素数之后,算法应该中断。我已经手动确认,在127之后,如果堆的顺序正确,我的算法应该将128识别为非素数,但这不是代码显示的内容
有什么建议吗
(当然,一旦基本算法开始工作,我将增加2(跳过所有非素数偶数)。我可能还将使筛选成为一个可匹配的。) 31后的筛堆: [127:127],[11:132],[2:128]
您到达132,即>128,因此在检查2*64之前点击
中断;
。您没有检查整个列表:
31后的筛堆:
[127:127],[11:132],[2:128]
您到达132,即>128,因此在检查2*64之前点击中断;
。您的问题是
top.multiple == current
关于
Integer current = 2;
Integer multiple;
如果我没记错的话,有一个绝对值很小的Integer
s缓存,-128
到127
,因此使用=
的比较会比较小于128的值的相同实例。但是从128开始,你会得到一个新的Integer
,对于current
,这是一个不同的对象由top.multiple引用的一个
使用equals
或声明int current;
进行比较以解决此问题
为了改进算法,请注意每个素数的倍数仅来自素数的平方。您的问题是
top.multiple == current
关于
Integer current = 2;
Integer multiple;
如果我没记错的话,有一个绝对值很小的Integer
s缓存,-128
到127
,因此使用=
的比较会比较小于128的值的相同实例。但是从128开始,你会得到一个新的Integer
,对于current
,这是一个不同的对象由top.multiple引用的一个
使用equals
或声明int current;
进行比较以解决此问题
要改进算法,请注意每个素数的倍数,只从素数的平方开始。投票结束:让陌生人通过检查来发现代码中的错误是无效的。你应该使用调试器或打印语句来识别(或至少隔离)问题,然后再提出更具体的问题(一旦你把它缩小到10行)。这个想法并不新鲜:@Daniel:当然,我没想到它会是新的。不过对我来说,它很新奇,也很有趣;@Oli:链接的代码在问题区域有打印语句。我对行为的描述足以让人说“啊哈”给我一个正确的答案。我包括了算法的摘要,以便更好地衡量。我已经测试了该算法,并怀疑它是我没有考虑到的Java语言功能或一些明显的错误。确实如此。我本可以做更多的工作,但我不需要。@theazureshadow:这正是为什么这个问题不适合这样做的原因。在发布问题之前,您应该在调试器中逐行检查代码,以消除出现明显错误的可能性。投票结束:让陌生人通过检查发现代码中的错误是无效的。您应该识别(或至少隔离)通过使用调试器或打印语句来解决问题,然后返回一个更具体的问题(一旦将问题缩小到10行)。这个想法并不新鲜:@Daniel:当然,我没想到它会是新的。不过,它对我来说既新奇又有趣;@Oli:链接的代码在问题区域有打印语句。我对行为的描述足以让人说“啊哈”给我一个正确的答案。我包括了算法的摘要,以便更好地衡量。我已经测试了该算法,并怀疑它是我没有考虑到的Java语言功能或一些明显的错误。确实如此。我本可以做更多的工作,但我不需要。@theazureshadow:这正是为什么这个问题不适合这样做的原因。在发布问题之前,您应该在调试器中逐行检查代码,以消除出现明显错误的可能性。这是一个堆,增加127后,新的顶部是[2:128]
,该部分工作正常。这是一个堆,增加127后,新的顶部是[2:128]
,这部分工作正常。这将教会我如何在对象上使用运算符!我怀疑这是我没有考虑到的Java语言特性(我正在编写一些简单的程序来学习Java)。谢谢,丹尼尔。是的,这是一个问题。很容易发现它