2 回答

TA貢獻1830條經驗 獲得超9個贊
弄清楚了,這就是代碼應該是什么樣子的
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

TA貢獻1871條經驗 獲得超8個贊
我已經突出顯示了錯誤:
// 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);
是模棱兩可的。 聲明兩種不同的 remove 方法:刪除列表中的第 i 個條目,以及 ,刪除等于 的條目。由于 a 可以轉換為 ,因此兩種方法都與參數的類型匹配,但與參數類型更接近,因此被使用,而您可能希望刪除(Integer)...您可以通過轉換參數來解決此問題:ArrayList<Integer>remove(int)remove(Integer)iintIntegerremove(int)
nums.remove((Integer) i);
這應該使代碼正常工作,但你很快就會意識到代碼相當慢。這是因為實際上是一個相當昂貴的操作,因為它涉及迭代整個操作,直到找到要刪除。也就是說,對于您淘汰的每個主要候選人,您都會與所有其他主要候選人進行交互。由于其中有很多,因此您的代碼將非常慢。remove(Integer)ListInteger
解決方案是選擇一個支持更有效地按值刪除的數據結構。這就是為什么每個人在實現此算法時使用a的原因。boolean[]
添加回答
舉報