【问题标题】:Why is my algorithm not giving the expected output?为什么我的算法没有给出预期的输出?
【发布时间】:2015-07-01 17:02:42
【问题描述】:

我正在尝试创建 Sieve of Eratosthenes 算法的 Java 实现。

我有以下代码,虽然输出不正确,但可以运行。

import java.util.ArrayList;
public class sieveOfEratosthenes {
    private static final ArrayList<Integer> test = new ArrayList<>();
    public static void main (String [] args) {
        java.util.Scanner tempInput = new java.util.Scanner(System.in);
        System.out.println("What number would you like the prime numbers to be generated to?");
        int maxPrime = tempInput.nextInt();
        for(int i = 2; i <= maxPrime; i++) {
            test.add(i);
        }
        getPrimeList(maxPrime);
    }

    private static void getPrimeList(int maxNumber) {
        int sqrtOfNum = (int) Math.sqrt(maxNumber);
        int temp = 0, i = 0;
        int currentPrime = test.get(i);
        boolean completed = false;
        i++;
        //do {
        while((completed == false) && (i < test.size())) {
            if(i >= test.size()) {
                completed = true;
            } else if((temp <= sqrtOfNum) ) {
                removeMultiples(currentPrime);
            }
            i++;
            if (i < test.size()) {
                currentPrime = test.get(i);
            }
        }
        //}while(completed == false && (i < test.size()));
        System.out.println("Prime numbers upto: " + maxNumber + ": " + test);
    }

    private static void removeMultiples(int primeToTest) {
        ArrayList<Integer> temp = new ArrayList<>();
        for (Integer toTest : test) {
            if (!(((toTest) % primeToTest) == 0)) {
                temp.add(toTest);
            }
        }
        test.clear();
        test.addAll(temp);
    }
}

程序给出的输出示例如下:

What number would you like the prime numbers to be generated to?
10
Prime numbers upto: 10: [3, 5, 9]

显然上面例子的输出应该是:

Prime numbers upto: 10: [2, 3, 5, 7]

【问题讨论】:

  • 在进行任何巧妙优化之前,尝试按照链接中实际描述的算法实现算法。我没有看到您“标记”非素数,而是在清除列表。只需先执行 wiki 页面概述中的四个步骤。这样调试会更容易。

标签: java algorithm arraylist sieve-of-eratosthenes


【解决方案1】:

您将test 初始化为[2,3,4,5...],将currentPrime 设置为2 (test[0]),删除它的倍数(删除2)。我相信当 i 变为 2 并且 test[2] = 7 时会发生类似的事情。

这不会发生在 3 和 5 中,因为您使用 i 前进通过 test,但同时也从 test 中删除项目,以便值 i 引用发生变化(因为该位置的值已经改变)。因此,在第一次通过while 循环结束时,i 已被提升到 2,而从未消除 3 或 5 的倍数(如果您使用更大的maxNumber,您会看到)。

【讨论】:

  • 击败我得到答案。我还建议简化您的条件语句。现在你有 !(((toTest) % primeToTest) == 0)。这可以简化为 toTest % primtToTest != 0。可能更容易阅读 :) 编辑:我只是注意到这将删除您当前正在检查的数字,因为 2 % 2 == 0, 2 永远不会被添加回来,所以我认为你可能需要调整它。
【解决方案2】:

埃拉托色尼筛算法说,当您考虑素数 currentPrime 时,您必须将其除自身之外的所有倍数标记为非素数。在您的removeMultiples 函数中,您还删除了currentPrime

您在getPrimeList 中的迭代方式对我来说似乎也有点奇怪。我认为您可能会摆脱 completed 变量和一些 i &gt;= test.size() 测试。 尝试类似:

import java.util.ArrayList;
public class sieveOfEratosthenes {
    private static final ArrayList<Integer> test = new ArrayList<>();
    public static void main (String [] args) {
        java.util.Scanner tempInput = new java.util.Scanner(System.in);
        System.out.println("What number would you like the prime numbers to be generated to?");
        int maxPrime = tempInput.nextInt();
        for(int i = 2; i <= maxPrime; i++) {
            test.add(i);
        }
        getPrimeList(maxPrime);
    }

    private static void getPrimeList(int maxNumber) {
        int sqrtOfNum = (int) Math.sqrt(maxNumber);
        int temp = 0, i = 0, current_prime = 0;
        //do {
        while(current_prime <= sqrtOfNum && i < test.size()) {
            current_prime = test.get(i);            
            removeMultiples(current_prime);
            i++;
        }
        //}while(completed == false && (i < test.size()));
        System.out.println("Prime numbers upto: " + maxNumber + ": " + test);
    }

    private static void removeMultiples(int primeToTest) {
        ArrayList<Integer> temp = new ArrayList<>();
        tmp.add(primeToTest);
        for (Integer toTest : test) {
            if (toTest%primeToTest != 0) {
                temp.add(toTest);
            }
        }
        test.clear();
        test.addAll(temp);
    }
}

【讨论】:

    猜你喜欢
    • 2021-08-18
    • 1970-01-01
    • 2023-04-09
    • 1970-01-01
    • 2019-11-13
    • 1970-01-01
    • 2012-08-08
    • 1970-01-01
    • 2018-09-18
    相关资源
    最近更新 更多