简体   繁体   English

埃拉托色尼的筛分(使用链接列表)

[英]Sieve of Eratosthenes (USING LINKEDLIST)

Im trying to figure out how i would manipulate Lists in order to find all the primes up to a number provided by the user, i have a list steps which im trying to follow which are我试图弄清楚我将如何操作列表以找到用户提供的所有素数,我有一个我试图遵循的列表步骤

create and fill list of possible primes创建和填充可能的素数列表

Basically an arrayList that contains all numbers up to the provided number, i have that part done基本上是一个包含所有数字直到提供的数字的arrayList,我已经完成了那部分

create list for the primes创建素数列表

i have that part down我记下了那部分

while there are still possible numbers虽然仍有可能的数字

That is, while the list of possibly-prime numbers is not empty.也就是说,虽然可能是素数的列表不为空。

add the first number from the list of possibles to the list of primes将可能列表中的第一个数字添加到素数列表中

Got that part down too把那部分也放下了

remove it and its multiples from the list of possible primes从可能的素数列表中删除它及其倍数

this is where i start to daze off a little, i thought i had that part down but im getting an error I dont know why.这是我开始有点发呆的地方,我以为我已经完成了那部分,但我收到了一个错误,我不知道为什么。

print the prime numbers打印质数

print the list of prime numbers, essentially just System.out.println(primes);打印质数列表,本质上只是System.out.println(primes);

Heres my code at the moment继承人我的代码此刻

import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
import java.util.Scanner;

public class Sieve {
public static void main(String[] args) {
    int maxNum;
    String howItsGoing, greatDetail;
    Scanner scnr = new Scanner(System.in);
    Scanner scnr2 = new Scanner(System.in);

    // get upper limit
    System.out.print("What's the biggest number I should check? ");
    maxNum = scnr.nextInt();

    // check for verbose mode
    System.out.print("Shall I tell you how it's going? ");
    howItsGoing = scnr2.nextLine().toUpperCase();

    System.out.print("Shall I tell you in great detail? ");
    greatDetail = scnr2.nextLine().toUpperCase();

    // create and fill list of possible primes
    List<Integer> nums = new LinkedList<>();

    for (int i = 2; i <= maxNum; i++) {
        nums.add(i);         
    }

    // create list for the primes
    List<Integer> primes = new ArrayList<>();
    // while there are still possible numbers

    // add the first number from the list of possibles to the list of primes
    for(int i=2; i<=maxNum; i++) {
        if(2 % i == 0) {
            nums.remove((Integer) i);
            primes.add((Integer) i);
        }
    }

        // remove it and its multiples from the list of possible primes

    // print the prime numbers
    System.out.println("Primes up to " + maxNum);
    System.out.println(nums);
    System.out.println(primes);


}

}

ignore the howItsGoing string and greatDetail, i will add those on later.忽略 howItsGoing 字符串和 greatDetail,我稍后会添加它们。

How would i get this program to work correctly, every other question has the solution in a boolean array, which is not what i want.我如何让这个程序正常工作,其他每个问题都有一个布尔数组的解决方案,这不是我想要的。 Any ideas?有任何想法吗?

OUTPUT输出

What's the biggest number I should check? 9
Shall I tell you how it's going? n
Shall I tell you in great detail? n
Primes up to 9
[3, 4, 5, 6, 7, 8, 9]
[2]

I've highlighted the bugs:我已经强调了错误:

    // remove it and its multiples from the list of possible primes
    for(int i=0; i<=maxNum; i++) {
        if(i % 2 == 0) {  // first bug
            nums.remove(i); // second bug
        }
    }

The first bug is that i % 2 == 0 checks whether i is a multiple of 2, but it should check whether it is a multiple of the current prime.第一个错误是 i % 2 == 0 检查 i 是否是 2 的倍数,但它应该检查它是否是当前素数的倍数。

The second bug is that第二个错误是

nums.remove(i);

is ambiguous.是模棱两可的。 ArrayList<Integer> declares two different remove methods: remove(int) which removes the i-th entry in the list, and remove(Integer) , which removes the entry equal to i . ArrayList<Integer>声明了两种不同的删除方法: remove(int)删除列表中的第 i 个条目, remove(Integer)删除等于i的条目。 Since an int can be converted to an Integer , both methods match the type of your argument, but remove(int) fits the argument type more closely and is therefore used, while you probably wanted remove(Integer) ... you can fix this by casting the argument:由于int可以转换为Integer ,这两种方法都匹配您的参数类型,但remove(int)更接近于参数类型,因此被使用,而您可能想要 remove(Integer) ...您可以解决这个问题通过铸造参数:

nums.remove((Integer) i);

This should get the code to work correctly, but you'll soon realize that the code is rather slow.这应该能让代码正常工作,但您很快就会意识到代码相当慢。 That's because remove(Integer) is actually a rather costly operation, as it involves iterating through the entire List until the Integer to remove is found.这是因为remove(Integer)实际上是一个相当昂贵的操作,因为它涉及遍历整个List直到找到要删除的Integer That is, for every prime candidate you eliminate, you interact with all the other prime candidates.也就是说,对于您消除的每个主要候选人,您都会与所有其他主要候选人进行互动。 Since there is a great many of those, your code will be very slow.由于其中有很多,您的代码将非常缓慢。

The solution is to pick a data structure that supports removal by value more efficiently.解决方案是选择一种更有效地支持按值删除的数据结构。 And that's why everyone is using a boolean[] when they implement this algorithm.这就是为什么每个人在实现这个算法时都使用boolean[]的原因。

Figured it out, this is what the code should look like想通了,这就是代码的样子

import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
import java.util.Scanner;

public class Sieve {
public static void main(String[] args) {
    int maxNum;
    boolean possible = true;
    String howItsGoing, greatDetail;
    Scanner scnr = new Scanner(System.in);
    Scanner scnr2 = new Scanner(System.in);

    // get upper limit
    System.out.print("What's the biggest number I should check? ");
    maxNum = scnr.nextInt();

    // check for verbose mode
    System.out.print("Shall I tell you how it's going? ");
    howItsGoing = scnr2.nextLine().toUpperCase();

    if (howItsGoing.startsWith("N")) {
        greatDetail = "N";
    } else {
        System.out.print("Shall I tell you in great detail? ");
        greatDetail = scnr2.nextLine().toUpperCase();
    }

    // create and fill list of possible primes
    List<Integer> nums = new LinkedList<>();

    for (int i = 2; i <= maxNum; i++) {
        nums.add(i);
    }

    // create list for the primes
    List<Integer> primes = new ArrayList<>();
    // while there are still possible numbers
    while (possible) {
        // add the first number from the list of possibles to the list of
        // primes

        primes.add(nums.get(0));

        if (howItsGoing.startsWith("Y")) {
            System.out.println();
            System.out.println();
            System.out.print("Found prime: ");
            System.out.printf("%1d ", nums.get(0));
            System.out.println();
        }
        // remove it and its multiples from the list of possible primes
        int divisor = nums.get(0);

        nums.remove(nums.get(0));

        for (int i = divisor; i <= maxNum; i++) {

            if (i % divisor == 0) {
                if (greatDetail.startsWith("Y")) {
                    System.out.println(
                            "    Removing " + i + " from possibles");
                }
                nums.remove((Integer) i);
            }

        }
        System.out.println();
        if (nums.size() > 0) {
            if (howItsGoing.startsWith("Y")) {
                System.out.print("Possibles:\n    ");
                for (int i = 0; i < nums.size(); i++) {
                    System.out.printf("%6d ", nums.get(i));
                }

            }
        }
        if (nums.size() < 1) {
            possible = false;
        }
    }

    // print the prime numbers
    System.out.println();
    System.out.println("Primes up to " + maxNum);
    for (int i = 0; i < primes.size(); i++) {
        System.out.printf("%6d ", primes.get(i));
    }

}
}

output输出

What's the biggest number I should check? 20
Shall I tell you how it's going? yes
Shall I tell you in great detail? yes


Found prime: 2 
Removing 2 from possibles
Removing 4 from possibles
Removing 6 from possibles
Removing 8 from possibles
Removing 10 from possibles
Removing 12 from possibles
Removing 14 from possibles
Removing 16 from possibles
Removing 18 from possibles
Removing 20 from possibles

Possibles:
     3      5      7      9     11     13     15     17     19 

Found prime: 3 
Removing 3 from possibles
Removing 6 from possibles
Removing 9 from possibles
Removing 12 from possibles
Removing 15 from possibles
Removing 18 from possibles

Possibles:
     5      7     11     13     17     19 

Found prime: 5 
Removing 5 from possibles
Removing 10 from possibles
Removing 15 from possibles
Removing 20 from possibles

Possibles:
     7     11     13     17     19 

Found prime: 7 
Removing 7 from possibles
Removing 14 from possibles

Possibles:
    11     13     17     19 

Found prime: 11 
Removing 11 from possibles

Possibles:
    13     17     19 

Found prime: 13 
Removing 13 from possibles

Possibles:
    17     19 

Found prime: 17 
Removing 17 from possibles

Possibles:
    19 

Found prime: 19 
Removing 19 from possibles


Primes up to 20
 2      3      5      7     11     13     17     19 

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

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