簡體   English   中英

埃拉托色尼的篩分(使用鏈接列表)

[英]Sieve of Eratosthenes (USING LINKEDLIST)

我試圖弄清楚我將如何操作列表以找到用戶提供的所有素數,我有一個我試圖遵循的列表步驟

創建和填充可能的素數列表

基本上是一個包含所有數字直到提供的數字的arrayList,我已經完成了那部分

創建素數列表

我記下了那部分

雖然仍有可能的數字

也就是說,雖然可能是素數的列表不為空。

將可能列表中的第一個數字添加到素數列表中

把那部分也放下了

從可能的素數列表中刪除它及其倍數

這是我開始有點發呆的地方,我以為我已經完成了那部分,但我收到了一個錯誤,我不知道為什么。

打印質數

打印質數列表,本質上只是System.out.println(primes);

繼承人我的代碼此刻

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


}

}

忽略 howItsGoing 字符串和 greatDetail,我稍后會添加它們。

我如何讓這個程序正常工作,其他每個問題都有一個布爾數組的解決方案,這不是我想要的。 有任何想法嗎?

輸出

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]

我已經強調了錯誤:

    // 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
        }
    }

第一個錯誤是 i % 2 == 0 檢查 i 是否是 2 的倍數,但它應該檢查它是否是當前素數的倍數。

第二個錯誤是

nums.remove(i);

是模棱兩可的。 ArrayList<Integer>聲明了兩種不同的刪除方法: remove(int)刪除列表中的第 i 個條目, remove(Integer)刪除等於i的條目。 由於int可以轉換為Integer ,這兩種方法都匹配您的參數類型,但remove(int)更接近於參數類型,因此被使用,而您可能想要 remove(Integer) ...您可以解決這個問題通過鑄造參數:

nums.remove((Integer) i);

這應該能讓代碼正常工作,但您很快就會意識到代碼相當慢。 這是因為remove(Integer)實際上是一個相當昂貴的操作,因為它涉及遍歷整個List直到找到要刪除的Integer 也就是說,對於您消除的每個主要候選人,您都會與所有其他主要候選人進行互動。 由於其中有很多,您的代碼將非常緩慢。

解決方案是選擇一種更有效地支持按值刪除的數據結構。 這就是為什么每個人在實現這個算法時都使用boolean[]的原因。

想通了,這就是代碼的樣子

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

}
}

輸出

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