为什么我的算法没有给出预期的输出?

时间:2015-07-01 17:02:43

标签: java algorithm arraylist sieve-of-eratosthenes

我正在尝试创建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]

2 个答案:

答案 0 :(得分:2)

您将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的倍数(如果你使用了更大的{{{ 1}})。

答案 1 :(得分:0)

Eratosthenes算法的筛子说,当你考虑一个素数currentPrime时,你必须将其所有倍数标记为非素数,除了它本身。在removeMultiples功能中,您还要删除currentPrime

你在getPrimeList中迭代的方式对我来说似乎有点奇怪。我想你可能会摆脱completed变量和一些i >= 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);
    }
}