I am trying to create an Java implementation of the Sieve of Eratosthenes algoritm.
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). I believe a similar things happens when i
gets to be 2 and 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). 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
).
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. In your removeMultiples
function you are removing also currentPrime
.
The way you iterate in getPrimeList
seems also a bit odd to me. I think you might get rid of the completed
variable and of some i >= test.size()
testing. 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);
}
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.