Java 埃拉斯托烯的筛分(使用LINKEDLIST)
我试图弄清楚我将如何操作列表,以便找到用户提供的数字以下的所有素数,我有一个列表步骤,我试图遵循这些步骤 创建并填写可能的素数列表 基本上是一个arrayList,它包含所有数字,直到提供的数字为止,我已经完成了这一部分 创建素数列表 我把那部分记下来了 虽然仍有可能的数字 也就是说,虽然可能的素数列表不是空的 将可能列表中的第一个数字添加到素数列表中 那部分也记下来了 从可能的素数列表中删除它及其倍数 这就是我开始有点发呆的地方,我以为我把那个部分搞坏了,但是我犯了一个错误,我不知道为什么 打印素数 打印素数列表,基本上就是System.out.println(素数)强> 这是我目前的密码Java 埃拉斯托烯的筛分(使用LINKEDLIST),java,list,sieve-of-eratosthenes,sieve,Java,List,Sieve Of Eratosthenes,Sieve,我试图弄清楚我将如何操作列表,以便找到用户提供的数字以下的所有素数,我有一个列表步骤,我试图遵循这些步骤 创建并填写可能的素数列表 基本上是一个arrayList,它包含所有数字,直到提供的数字为止,我已经完成了这一部分 创建素数列表 我把那部分记下来了 虽然仍有可能的数字 也就是说,虽然可能的素数列表不是空的 将可能列表中的第一个数字添加到素数列表中 那部分也记下来了 从可能的素数列表中删除它及其倍数 这就是我开始有点发呆的地方,我以为我把那个部分搞坏了,但是我犯了一个错误,我不知道为什么 打
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);
}
}
我强调了这些错误:
// 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
}
}
这是模棱两可的ArrayList
声明了两种不同的删除方法:remove(int)
,用于删除列表中的第i个条目;和remove(Integer)
,用于删除等于i
的条目。由于int
可以转换为Integer
,因此这两种方法都与参数的类型匹配,但是remove(int)
更适合参数类型,因此使用它,而您可能需要remove(Integer)。。。您可以通过强制转换参数来解决此问题:
nums.remove((Integer) i);
这应该可以让代码正常工作,但您很快就会意识到代码相当慢。这是因为remove(Integer)
实际上是一个成本相当高的操作,因为它需要迭代整个列表
,直到找到要删除的整数。也就是说,对于你淘汰的每一个主要候选人,你都会与所有其他主要候选人互动。因为有很多这样的代码,所以您的代码将非常慢
解决方案是选择一种支持更有效地按值删除的数据结构。这就是为什么每个人在实现这个算法时都使用布尔[]
。弄明白了,这就是代码应该是什么样子
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));
}
}
}
谢谢,我把它修好了,但是现在我正在检查第一个数字是否可以被2整除,这显然是真的,所以它去掉了2,剩下的数字呢,我该怎么做?关于效率,我知道它很慢,我只是在考试前练习列表。我一直在做随机程序
nums.remove((Integer) i);
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