I have a prime-finding class here that needs improvement.
Sample result:
Number of primes? 10 2 3 5 7 11 13 17 19 23 29 Total calculation time: 6 milliseconds Calculation time per number: 0.6 milliseconds
As more prime numbers are calculated, the calculation time per number increases.
100 primes:
Number of primes? 100 2 3 5 7 11 13 17 19 23 29 31 37 41 43 47 53 59 61 67 71 ... 419 421 431 433 439 443 449 457 461 463 467 479 487 491 499 503 509 521 523 541 Total calculation time: 23 milliseconds Calculation time per number: 0.23 milliseconds
1000 primes:
Number of primes? 1000 2 3 5 7 11 13 17 19 23 29 31 37 41 43 47 53 59 61 67 71 ... 7727 7741 7753 7757 7759 7789 7793 7817 7823 7829 7841 7853 7867 7873 7877 7879 7883 7901 7907 7919 Total calculation time: 269 milliseconds Calculation time per number: 0.269 milliseconds
Main
class
import java.util.NoSuchElementException;
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
System.out.println("Number of primes?");
boolean validInput = false;
int i = 0;
while (!validInput) {
try {
i = sc.nextInt();
validInput = true;
} catch (NoSuchElementException e) {
// validInput stays false
System.out.println("That's not an integer. Try again:");
sc.next();
}
}
boolean warning = false;
if (i > 50000) {
System.out
.println("The program will not allow this many primes to be calculated!");
sc.close();
return;
} else if (i > 20000) {
System.out.println("WARNING! Large amount of memory is needed!");
warning = true;
}
if (i > 6400) {
System.out
.println("WARNING! It will take more that 2 millisecond per number for calculation!");
warning = true;
} else if (i > 3450) {
System.out
.println("WARNING! It will take more that 1 millisecond per number for calculation!");
warning = true;
}
if (i > 6650) {
System.out
.println("WARNING! It will take more that 15 seconds for calculation!");
warning = true;
}
if (warning) {
System.out.println("Are you sure you want to continue? (Y/N)");
while (true) {
String yn = sc.nextLine();
if (yn.equalsIgnoreCase("Y")) {
break;
} else if (yn.equalsIgnoreCase("N")) {
sc.close();
System.out.println("Bye!");
return;
}
}
}
long l = System.currentTimeMillis();
Prime p = new Prime(i);
printSortedLongArray(p.getPrimes(i));
long timeNow = System.currentTimeMillis();
System.out.println("Total calculation time: " + (timeNow - l)
+ " milliseconds");
System.out.println("Calculation time per number: "
+ ((timeNow - l) / (double) i) + " milliseconds");
System.out.println("Bye!");
sc.close();
}
public static void printSortedLongArray(long[] a) {
long nums = 0;
int len = Long.toString(a[a.length - 1]).length();
for (long l : a) {
System.out.print(l);
nums++;
if (nums % 10 == 0) {
System.out.println();
continue;
}
for (int i = Long.toString(l).length(); i <= len; i++) {
System.out.print(" ");
}
}
if (nums % 10 != 0) {
System.out.println();
}
}
}
Prime
class
import java.util.LinkedList;
import java.util.List;
public class Prime {
long[] primes;
public Prime(int max) {
primes = new long[max];
int j = 0;
for(long i = 1; j < max; i++) {
if(isPrime(i)) {
primes[j] = i;
j++;
}
}
}
public long[] getPrimes(int max) {
return primes;
}
public static boolean isPrime(long l) {
return l != 1 && getFactors(l).length == 2;
}
public static long[] getFactors(long l) {
List<Long> list = new LinkedList<Long>();
for(long i = 1 ; i <= l / 2 ; i++) {
if(l % i == 0) {
list.add(i);
}
}
list.add(l);
long[] result = new long[list.size()];
int len = list.size();
for(int i = 0; i < len; i++) {
result[i] = list.get(i);
}
return result;
}
}
My questions:
- Is there a better way of doing this? If so, how?
- Is the separate
Prime
class necessary?
Any criticism is welcome!