-1

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

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

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.

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]
MaroTS
  • 35
  • 9

2 Answers2

0

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.

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. 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:

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. 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.

meriton
  • 68,356
  • 14
  • 108
  • 175
  • Thank you i fixed it up, but right now im checking if the first number is divisible by 2, which is obviously true, so it removes 2, what about the rest of the numbers, how would i do that? and about the efficiency, i know its slow, im really just practicing Lists before my exam. i've been making random programs – MaroTS Mar 12 '19 at 01:00
0

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 
MaroTS
  • 35
  • 9