简体   繁体   English

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

[英]Why is my algorithm not giving the expected output?

I am trying to create an Java implementation of the Sieve of Eratosthenes algoritm. 我正在尝试创建Eratosthenes算法筛网的Java实现。

I have the following code, which runs, although gives an incorrect output. 我有下面的代码,尽管给出了错误的输出,但仍可以运行。

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);
    }
}

An example of the output given by the program is as follows: 该程序给出的输出示例如下:

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

Obviously the output for the above example should be: 显然,以上示例的输出应为:

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

You initialize test to be [2,3,4,5...] , set currentPrime to 2 ( test[0] ), remove multiples of this (removing the 2). 您将test初始化为[2,3,4,5...] ,将currentPrime设置为2( test[0] ),删除其倍数(删除2)。 I believe a similar things happens when i gets to be 2 and test[2] = 7. 我相信当i成为2且test[2] = 7时也会发生类似的情况。

This does not happen with 3 and 5 because you are using i to advance through test , but are also removing items from test so that the values i references changes (because the value in that position has changed). 在3和5上不会发生这种情况,因为您正在使用i进行test ,但同时也从test删除项目,以便i引用的值发生更改(因为该位置的值已更改)。 So at the end of the first time through the while loop, i has been advanced to 2 without ever eliminated multiples of 3 or 5 (which you'd see if you used a bigger maxNumber ). 因此,在第一次通过while循环结束whilei已经提高到了2,而从未消除3或5的倍数(如果使用更大的maxNumber ,您会看到的)。

The Sieve of Eratosthenes algorithm says that when you consider a prime currentPrime you have to mark as non-primes all its multiples except from itself. Eratosthenes的Sieve算法说,当您考虑一个质数currentPrime您必须将其所有倍数(除自身以外)标记为非质数。 In your removeMultiples function you are removing also currentPrime . removeMultiples函数中,您还将同时删除currentPrime

The way you iterate in getPrimeList seems also a bit odd to me. getPrimeList进行迭代的方式对我来说也有些奇怪。 I think you might get rid of the completed variable and of some i >= test.size() testing. 我认为您可能会i >= test.size() completed变量和某些i >= test.size()测试。 Try something like: 尝试类似的方法:

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);
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM