当前位置: 首页 > 知识库问答 >
问题:

埃拉托斯特尼实施的筛子不检查某些数字

松波
2023-03-14

我正在编写一个程序,使用厄拉多塞算法的好筛子来寻找质数(虽然有一个扭曲)。为了将所需字节数组的大小减半,我不表示任何偶数,而坚持使用奇数(通过整数除以2来计算它们在数组中的位置)。

然而,我有一个问题。我的程序似乎无法将17或113识别为质数,尽管它们确实是质数。这是我的代码:

public class Eratosthes {

    byte[] checklist;
    int range;

    public EratosthesConcurrent(int range) {
        this.range = range/2;
        this.checklist = new byte[this.range];
        this.initAllChecked();
        this.findPrimesSeq();
        this.printPrimes();
    }

    private void initAllChecked(){
        for(int i = 1; i < checklist.length; i++){
            checklist[i] = 1;
        }
    }

    private void crossOut(int i){
        checklist[i/2] = 0;
    }

    private void findPrimesSeq(){
        int curr = 3;
        outer: while(curr < range*2){
            for(int i = curr*curr; i < range*2; i+=2*curr){
                if(i != curr && i%curr == 0){
                    if(i == 113){
                        System.out.println(curr);
                    }
                    crossOut(i);
                }
            }

            secondLoop: for(int i = curr; i < range*2; i++){
                if(checklist[i/2] == 1 && curr != i){
                    curr = i;
                    break secondLoop;
                } else if(i == range*2-1 || i == range*2-2){ //Should be changed, might miss the last prime
                    break outer;
                }
            }
        }
    }

    public void printPrimes(){
        for(int i = 1; i < range; i++){
            if(checklist[i] == 1){
                System.out.println("Prime found: " + ((i*2)+1));
            }
        }
    }
}

将以下内容添加到 crossOut 方法不会生成任何输出:

if(i == 17 || i == 113){
    System.out.println("Found one of the numbers");
}

这对我来说很奇怪,因为程序的打印输出不包括17和113,因此不检查它们的任何倍数。这给我留下了一个字节数组,其中所有素数都被检查了...以及 17 或 113 的任意倍数。

如果有人能在我的程序中找到错误,我会很高兴的。我自己已经调试了几个小时,没有结果。提前谢谢。

共有2个答案

钱振
2023-03-14
for(int i = curr*curr; i < range*2; i+=2*curr){

第一个值= 9,然后到15

货币= 3 - 3*3 = 9

i = 2 * curr = 9 6

伪:

outerNum = sqrt[range]
array[boolean] size of range
array[0 & 1] = false

for i = 2 to outernum
       for j  = i to range
           if j % i != 0
               array[j] = false

for i = array[boolean] length
     print if array[i] = true

这是从记忆中得出的,所以如果有任何错误,请原谅。

刁文光
2023-03-14

问题似乎是你没有检查2除法。

您在某个时刻调用了crossOut(16)(特别是作为44的倍数),它去掉了 17的相应值。同样, 112导致113被删除。

改变:

if (i != curr && i % curr == 0) {

到:

if (i % 2 != 0 && i != curr && i % curr == 0) {

这两个都被打印为prime。

另外,我有点担心这个循环到底在做什么-我没有太详细地查看输出,虽然它实际上看起来是所有的素数,但我想你应该循环curr的倍数,第一个是2*curr(not >), 0.05的增量,虽然我并不是说你所做的是不正确的,因为我需要更多的时间来确切理解你的代码是如何解决这个问题的。

 类似资料:
  • 我在我的一个班级里做的一个作业,我们必须实现一个厄拉多塞的筛子。我已经尝试了七次来得到一个有效的代码,并且尝试了整合我研究过的许多解决方案。我终于有一个可以输出数字的了。不幸的是,它同时打印合数和质数,但不打印2。 我的代码如下: 我怀疑我的循环有问题。我修复了前两个循环的和变量,以便它从2开始打印出来,问题似乎是在我将数组初始化为true后,它没有将合数标记为。 提前感谢你的帮助。

  • 我正在尝试编写一个程序来实现对埃拉托西的筛选。我可以从2到任何给定的结束编号,但我们正在处理的赋值要求我们输入起始值。我完全被卡住了。我试过很多不同的代码,但它总是给我奇怪的答案。 我的起点是起始值,终点是结束值。我基本上想找到这个范围的素数。谢谢!!!

  • 做一个简单的筛子很容易: 但是当N非常大并且我无法在内存中持有这种数组时,该怎么办?我已经查找了分段筛方法,它们似乎涉及查找素数,直到sqrt(N),但我不明白它是如何工作的。如果 N 非常大(比如 10^18)怎么办?

  • 在一个类作业中,我被要求用Java编写Eratostenes筛选代码,我的代码效率非常低。运行时间不长,但我相当肯定,除了像我一样列出所有内容外,还有其他循环的空间。。 这是我的代码: 基本上,我所做的是将所有不是质数的元素设置为true… 所以我的主要2个问题是1。有没有办法实现一个循环,使代码更短2。如何打印此数组中所有为 true(质数)的元素

  • 我在python中找到了一个示例代码,它给出了直到< code>n的所有素数,但我就是不明白,为什么它会这样做? 我读过维基百科上关于埃拉托色尼筛子的文章,但根本不知道它是如何工作的。 请解释一下循环是如何工作的。 EDIT-发现代码都错了,因为它表示25为素数,通过更深入的搜索发现这不是筛子,有人能展示一个利用python中筛子的生成器并解释它吗

  • 我正在尝试实现筛选算法,它会询问连续数字列表的大小,并打印出该列表中的素数,但我收到了一个seg错误:11错误。 这是我的代码: