My program doesn't show each of the correct list it's being sorted, number of comparison and number of assignment except bubble sorting method. I think I missed to reset the input string but could not figure out the way to reset input.
Is there any way to sort one input in different sorting method.
Here is my code:
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Arrays;
import java.util.Scanner;
/**
* Create a program that does head-to-head comparisons between four sorting
* methods: improved bubble sort; selection sort; insertion sort; and Shell
* sort.
*
*/
public class SortAlgorithms {
private static char tracing;
private static char list;
private static int numAsgn = 0;
private static int numComp = 0;
private static int size;
private static int min;
private static int max;
private static final Scanner KBD = new Scanner(System.in);
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
System.out.print("How many elements do you want in the list? ");
size = KBD.nextInt();
System.out.print("What are the smallest and largest values for lsit elements? ");
min = KBD.nextInt();
max = KBD.nextInt();
KBD.nextLine();
pause();
System.out.print("Would you like to see the list before it's sorted? ");
list = Character.toUpperCase(br.readLine().charAt(0));
System.out.print("Would you like to see the list as it's being sorted? ");
tracing = Character.toUpperCase(br.readLine().charAt(0));
pause();
sortNumbers();
}
// prompt the user and wait for them to press enter
private static void pause() {
System.out.print("\n...Press enter...");
KBD.nextLine();
System.out.println();
}
/**
* Sort a list of integer values, generated randomly.
*/
public static void sortNumbers() {
resetCounts();
Integer[] numbers = randomNumbers(size, min, max);
if (list == 'Y') {
System.out.println("Here is the list: " + Arrays.toString(numbers));
pause();
}
System.out.printf("\n%1s%25s%20s%20s\n", "Method", "#COMP", "#ASGN", "#OPS");
bubbleSort(numbers);
System.out.printf("%1s%25d%20d%20d\n", "Bubble", numComp, numAsgn, numAsgn + numComp);
selectionSort(numbers);
System.out.printf("%1s%22d%20d%20d\n", "Selection", numComp, numAsgn, numAsgn + numComp);
insertionSort(numbers);
System.out.printf("%1s%22d%20d%20d\n", "Insertion", numComp, numAsgn, numAsgn + numComp);
shellSort(numbers);
System.out.printf("%1s%26d%20d%20d\n", "Shell", numComp, numAsgn, numAsgn + numComp);
}
/**
* Reset the operation counts to zero.
*/
public static void resetCounts() {
numAsgn = 0;
numComp = 0;
}
/**
* Generate an array of random values.
*
* #param howMany the length of the list to be generated.
* #param lo the smallest value allowed in the list
* #param hi the largest value allowed in the list
*/
public static Integer[] randomNumbers(int size, int min, int max) {
int range = max - min + 1;
Integer[] result = new Integer[size];
for (int i = 0; i < size; ++i) {
result[i] = (int) (min + range * Math.random());
}
return result;
}
/**
* Perform bubble sort on the given array.
*
* #param a the array to sort.
*/
public static <T extends Comparable<? super T>>
void bubbleSort(T[] a) {
for (int i = a.length - 1; i > 0; --i) {
boolean elementSwapped = false;
//numComp++;
for (int j = 0; j < i; ++j) {
numComp++;
if (a[j].compareTo(a[j + 1]) > 0) {
numAsgn += 3;
T temp = a[j + 1];
a[j + 1] = a[j];
a[j] = temp;
elementSwapped = true;
}
}
if (!elementSwapped) {
break;
}
//if (tracing == 'Y') {
System.out.println("one more bubbled up: "
+ Arrays.toString(a));
//}
}
}
/**
* Perform insertion sort on the given array.
*
* #param a the array to sort.
*/
public static <T extends Comparable<? super T>>
void insertionSort(T[] a) {
for (int i = 0; i < a.length - 1; ++i) {
int p = i + 1;
T temp = a[p];
++numAsgn;
while (p > 0 && a[p - 1].compareTo(temp) > 0) {
++numComp;
a[p] = a[p - 1];
++numAsgn;
--p;
}
if (p > 0) {
++numComp; // count the last a[p-1] comparison
}
a[p] = temp;
++numAsgn;
//if (tracing == 'Y') {
System.out.println("one more inserted: " + Arrays.toString(a));
//}
}
}
/**
* Perform selection sort on the given array. if tracing, show the array
* after each selection round.
*
* #param a the array to sort
*/
public static <T extends Comparable<? super T>>
void selectionSort(T[] a) {
for (int i = 0; i < a.length - 1; ++i) {
int p = i;
++numAsgn;
for (int j = i + 1; j < a.length; ++j) {
++numComp;
if (a[j].compareTo(a[p]) < 0) {
p = j;
++numAsgn;
}
}
T temp = a[i];
a[i] = a[p];
a[p] = temp;
++numAsgn;
//if (tracing == 'Y') {
System.out.println("one more selected: " + Arrays.toString(a));
//}
}
}
/**
* Perform shell sort on the given array.
*
* #param a the array to sort.
*/
public static <T extends Comparable<? super T>>
void shellSort(T[] a) {
int gap = a.length / 2;
++numComp;
while (gap >= 1) {
if (gap % 2 == 0) {
++gap;
}
++numComp;
for (int i = gap; i < a.length; ++i) {
++numAsgn;
int p = i;
T temp = a[p];
++numComp;
while (p >= gap && a[p - gap].compareTo(temp) > 0) {
a[p] = a[p - gap];
p -= gap;
++numAsgn;
}
a[p] = temp;
++numAsgn;
}
//if (tracing == 'Y') {
System.out.println("...gap=" + gap + ": " + Arrays.toString(a));
// }
gap /= 2;
}
}
/**
* Calculate how many operations a list of the given length should take.
*
* #param numItems the number of elements in a list.
* #return the number of operations expected (on average) to sort that list
*/
private static int expect(int numItems) {
return (numItems * numItems + numItems) * 5 / 4;
}
}
You are overriding array numbers each time you sort, so since bubbleSort is the first sorting method, you only get to see that one. Each consecutive sorting method just operates on a sorted array. Also since you've defined your counts as member variables, you need to call resetCounts() right before each method to get a fresh count. Making a copy of the array before you pass it to each sorting method, and resetting the counts should fix this.
System.out.printf("\n%1s%25s%20s%20s\n", "Method", "#COMP", "#ASGN", "#OPS");
resetCounts();
bubbleSort(Arrays.copyOf(numbers, numbers.length));
System.out.printf("%1s%25d%20d%20d\n", "Bubble", numComp, numAsgn, numAsgn + numComp);
resetCounts();
selectionSort(Arrays.copyOf(numbers, numbers.length));
System.out.printf("%1s%22d%20d%20d\n", "Selection", numComp, numAsgn, numAsgn + numComp);
resetCounts();
insertionSort(Arrays.copyOf(numbers, numbers.length));
System.out.printf("%1s%22d%20d%20d\n", "Insertion", numComp, numAsgn, numAsgn + numComp);
resetCounts();
shellSort(numbers);
System.out.printf("%1s%26d%20d%20d\n", "Shell", numComp, numAsgn, numAsgn + numComp);
Related
I've been writing practice code for the AP java exam and I made a program that is supposed to simulate a game of war.
I made two methods, one for dealing the cards, and the other for the game.
I made a for loop with an if statement in it to iterate through the ArrayList and compare each element, it awards a point to which every element was higher.
But the issue is at the end, it just returns the scores as zero.
Can anyone tell me what I'm doing wrong?
import java.util.ArrayList;
public class Warr_Card_Game {
public static void main(String[] args) {
ArrayList<Integer> Hand1 = new ArrayList<Integer>(26); //This is player 1's hand
ArrayList<Integer> Hand2 = new ArrayList<Integer>(26); //This is player 2's hand
Dealer(Hand1, Hand2);
System.out.println(Hand1.size() + "\n" + Hand2.size()); // to ensure both hands are the same size
for(int i= 0; i < Hand1.size(); i++) {
System.out.println(Hand1.get(i) + " " + Hand2.get(i)); // to see live gameplay
}
Game(Hand1,Hand2);
if (Game(Hand1, Hand2) == true ) {
System.out.println("Player 1 Wins");// to see who won
}
else if(Game(Hand1, Hand2) == false) {
System.out.println("Player 2 Wins");
}
}
/**
*
* #param arr
* #param arr2
* acts as a dealer in dealing the cards to each player
*/
public static void Dealer(ArrayList<Integer> arr, ArrayList<Integer> arr2) {
for(int x = 0; x <= 51; x++) {
int i = (int)(Math.random()*13)+2;
if(x >= 26) {
arr.add(i);
}
else {
arr2.add(i);
}
}
}
/**
*
* #param arr
* #param arr2
* #return
* acts as gameplay to compare each card and award points accordingly
*/
public static boolean Game(ArrayList<Integer> arr, ArrayList<Integer> arr2) {
int score1 = 0;
int score2 = 0;
for(int i = 0; i >= 26; i++) {
System.out.println(arr.get(i) + arr2.get(i) + "\t" + score1 + " " + score2);
if(arr.get(i) > arr2.get(i)) {
score1+= 1;
}
else if (arr.get(i) < arr2.get(i)) {
score2 += 1 ;
}
}
return (score1>score2); // returns if score1 is or is not higher than score 2
}
}
there's a problem with your for-loop, so no scores added...
for(int i = 0; i >= 26; i++)
try
for(int i = 0; i < 26; i++)
Try changing the loop logic in your Game method.
Specifically change:
for(int i = 0; i >= 26; i++) {
To:
for(int i = 0; i <= 25; i++) {
The original implementation won't perform any loops because i is not >= 26. In the changed version, it should loop through values 0..25 as expected.
I have a program that sorts randomly generated numbers from least to greatest or greatest to least depending on the users choice. 2 problems are occurring.
When the user does Insertion Sorting with Descending, the randomly generated numbers and sorting numbers output like this for example:
Randomly Generated Numbers:
89 90 2 830 399
After sorting using the Insertion Sort, Using Descending Order, the array is:
89 90 2 830 399
It's weird because my other methods are EXACTLY the same, and they work fine, but for some reason this doesn't work.
Here is my code:
import javax.swing.*;
import java.lang.reflect.Array;
import java.util.Random;
public class RoutineSorter {
private static int[] generateRandomArray(int size, int randomMax) {
int[] array = new int[size];
Random randomGenerator = new Random();
for (int i = 0; i < size; i++) {
array[i] = randomGenerator.nextInt(randomMax);
}
return array;
}
public static void main(String[] args) {
int MethodChoice = Integer.parseInt(JOptionPane.showInputDialog("What method would you like to use to sort the random numbers" + "\n" + "1 - Selection Sort" + "\n" + "2 - Bubble Sort" + "\n" + "3 - Insertion Sort" + "\n" + "4 - Quick Sort"));
int iTotalCount = Integer.parseInt(JOptionPane.showInputDialog("What is the total number of integers?"));
int SortOrder = Integer.parseInt(JOptionPane.showInputDialog("1 - Ascending, " + "2 - Descending"));
int[] array = generateRandomArray(iTotalCount, 1001);
System.out.println("Randomly Generated number list: ");
for (int i: array) {
System.out.print(i + " ");
}
System.out.println("\n---------------------------------");
if (MethodChoice == 1) {
if (SortOrder == 2) {
selectionSortReverse(array);
System.out.println("After sorting using the Selection Sort, " + "Using Descending Order" + " " + "the array is: ");
} else if (SortOrder == 1) {
selectionSort(array);
System.out.println("After sorting using the Selection Sort," + " the array is:");
}
} else if (MethodChoice == 2) {
if (SortOrder == 2) {
bubbleSortReverse(array);
System.out.println("After sorting using the Bubble Sort, " + "Using Descending Order" + " " + "the array is: ");
} else if (SortOrder == 1) {
bubbleSort(array);
System.out.println("After sorting using the Bubble Sort," + " the array is:");
}
} else if (MethodChoice == 3) {
if (SortOrder == 2) {
insertionSortReverse(array);
System.out.println("After sorting using the Insertion Sort, " + "Using Descending Order" + " " + "the array is: ");
} else if (SortOrder == 1) {
insertionSort(array);
System.out.println("After sorting using the Insertion Sort," + " the array is:");
} else if (MethodChoice == 4) {
if (SortOrder == 2) {
}
}
for (int i: array) {
System.out.print(i + " ");
}
}
}
public static void quickSort(int data[], int low, int high) {
int partitionLoc;
if (low < high) {
partitionLoc = partition(data, low, high);
quickSort(data, low, partitionLoc - 1);
quickSort(data, partitionLoc + 1, high);
}
}
public static void quickSortReverse(int data[], int low, int high) {
int partitionLoc;
if (low > high) {
partitionLoc = partition(data, low, high);
quickSort(data, low, partitionLoc - 1);
quickSort(data, partitionLoc + 1, high);
}
}
public static int partition(int data2[], int left, int right) {
boolean moveLeft = true;
int separator = data2[left];
while (left < right) {
if (moveLeft == true) {
while ((data2[right] >= separator) && (left < right)) {
right--;
}
data2[left] = data2[right];
moveLeft = false;
} else {
while ((data2[left] <= separator) && (left < right)) {
left++;
}
data2[right] = data2[left];
moveLeft = true;
}
}
data2[left] = separator;
return left;
}
public static void bubbleSort(int data[]) {
//Loop to control number of passes
for (int pass = 1; pass < data.length; pass++) {
//Loop to control # of comparisons for length of array-1
for (int element = 0; element < data.length - 1; element++) {
//compare side-by-side elements and swap them if
//first element is greater than second element
if (data[element] > data[element + 1]) {
swap(data, element, element + 1); //call swap method
}
}
}
}
public static void bubbleSortReverse(int data[]) {
//Loop to control number of passes
for (int pass = 1; pass < data.length; pass++) {
//Loop to control # of comparisons for length of array-1
for (int element = 0; element < data.length - 1; element++) {
//compare side-by-side elements and swap them if
//first element is greater than second element
if (data[element] < data[element + 1]) {
swap(data, element, element + 1); //call swap method
}
}
}
}
public static void swapBubble(int array2[], int first, int second) {
int hold = array2[first];
array2[first] = array2[second];
array2[second] = hold;
}
public static void insertionSort(int data[]) {
int insert;
for (int next = 1; next < data.length; next++) {
insert = data[next];
int moveItem = next;
while (moveItem > 0 && data[moveItem - 1] > insert) {
data[moveItem] = data[moveItem - 1];
moveItem--;
}
data[moveItem] = insert;
}
}
public static void insertionSortReverse(int data[]) {
int insert;
for (int next = 1; next < data.length; next++) {
insert = data[next];
int moveItem = next;
while (moveItem < 0 && data[moveItem - 1] < insert) {
data[moveItem] = data[moveItem - 1];
moveItem--;
}
data[moveItem] = insert;
}
}
public static void selectionSort(int data[]) {
int smallest;
for (int i = 0; i < data.length - 1; i++) {
smallest = i;
//see if there is a smaller number further in the array
for (int index = i + 1; index < data.length; index++) {
if (data[index] < data[smallest]) {
swap(data, smallest, index);
}
}
}
}
public static void selectionSortReverse(int data[]) {
int smallest;
for (int i = 0; i < data.length - 1; i++) {
smallest = i;
//see if there is a smaller number further in the array
for (int index = i + 1; index < data.length; index++) {
if (data[index] > data[smallest]) {
swap(data, smallest, index);
}
}
}
}
public static void swap(int array2[], int first, int second) {
int hold = array2[first];
array2[first] = array2[second];
array2[second] = hold;
}
}
In the method insertionSortReverse() there is the mistake at the beginning of the while loop:
while (moveItem < 0 &&
It should be
while (moveItem > 0 &&
I suppose...
I fixed it. The problem was my insertionSortReverse() subroutine, one of the signs was the wrong way, so I put it to the opposite.
BEFORE
public static void insertionSortReverse(int data[]) {
int insert;
for (int next = 1; next < data.length; next++) {
insert = data[next];
int moveItem = next;
while (moveItem < 0 && data[moveItem - 1] < insert) {
data[moveItem] = data[moveItem - 1];
moveItem--;
}
data[moveItem] = insert;
}
}
AFTER
public static void insertionSortReverse(int data[]) {
int insert;
for (int next = 1; next < data.length; next++) {
insert = data[next];
int moveItem = next;
while (moveItem > 0 && data[moveItem - 1] < insert) {
data[moveItem] = data[moveItem - 1];
moveItem--;
}
data[moveItem] = insert;
}
}
I wrote a function that recursively calculates the binomical coefficient term of n and k using the memoizazion methood, I get an OutOfBoundException when i execute, I'll be happy to hear some directions about the mistake I've done.
Thank you all.
public class Binomial {
public static void main(String[] args) {
int n = Integer.parseInt(args[0]);
int k = Integer.parseInt(args[1]);
StdOut.print(binomial(n, k));
}
/**
* Recursively calculates the binomical coefficient term of n and k using
* the memoizazion methood
*
* #param n
* the upper nonnegative integer of the binomical coefficient
* #param k
* the lower nonnegative integer of the binomical coefficient
* #returns the computed binomical coefficient
*/
public static long binomial(int n, int k) {
long[][] mem = new long[n + 1][k + 1];
for (int i = 0; i <= n; i++) {
for (int j = 0; j <= n; j++) {
mem[i][j] = -1;
}
}
return binomial(n, k, mem);
}
public static long binomial(int n, int k, long[][] mem) {
if (k > n)
return 0;
if (k == 0 || n == 0)
return 1;
if (mem[n - 1][k] == -1) {
mem[n - 1][k] = binomial(n - 1, k, mem);
}
if (mem[n - 1][k - 1] == -1) {
mem[n - 1][k - 1] = binomial(n - 1, k - 1, mem);
}
return (mem[n - 1][k] + mem[n - 1][k - 1]);
}
}
A very simple mistake cause this error in function public static long binomial(int n, int k) change n in inner for with k, I mean :
public static long binomial(int n, int k) {
long[][] mem = new long[n + 1][k + 1];
for (int i = 0; i <= n; i++) {
for (int j = 0; j <= k; j++) {
mem[i][j] = -1;
}
}
return binomial(n, k, mem);
}
is your correct function.
I created my own implementation of merge sort, I tested it that it works. How ever I am not sure if it's O(N Log(N)) as it should be, or it's O(N^2), can you please look at my code and tell?
SortedList
public abstract class SortedList {
public final ArrayList<Integer> params = new ArrayList<Integer>();
public void add(int... params) {
for (int parameter : params) {
this.params.add(parameter);
}
}
abstract public void sort();
public void print() {
for (int parameter : params) {
System.out.print(parameter + " ");
}
System.out.println();
}
}
MargeSort
public class MargeSort extends SortedList{
private int buffer[];
#Override
public void sort() {
buffer = new int[params.size()];
for(int i = 1; i < params.size(); i *= 2){
sort(i);
}
}
private void sort(int interval) {
for(int i = 0; i < params.size() - interval; i += interval * 2){
sort(i, i + interval, interval);
}
}
private void sort(int index1, int index2, int interval) {
int startingIndex = index1;
int index1MaxValue = index1 + interval;
int index2MaxValue = index2 + interval;
if(index2MaxValue >= params.size()){
index2MaxValue = params.size();
}
int counter = 0;
for(counter = 0; index1 < index1MaxValue && index2 < index2MaxValue; counter++){
int param1 = params.get(index1);
int param2 = params.get(index2);
if(param1 < param2){
buffer[counter] = param1;
index1++;
}
else{
buffer[counter] = param2;
index2++;
}
}
int index, indexMaxValue;
if(index1 < index1MaxValue){
index = index1;
indexMaxValue = index1MaxValue;
}
else{
index = index2;
indexMaxValue = index2MaxValue;
}
while(index < indexMaxValue){
int param = params.get(index);
buffer[counter] = param;
index++;
counter++;
}
for(int i = 0; i < interval * 2 && i + startingIndex < params.size(); i++){
params.set(i + startingIndex, buffer[i]);
}
}
}
sort(int) is called lg N times, where N = params.size(). [lg N here and everywhere further means ceil(lg N)]
Loop in sort(int) loops N / (interval / 2) times, where interval in [1 .. lgN], calling sort(...), which takes nr of steps, which is lineary depends on its' interval arg.
So, nr of steps is:
Sigma(k in from 1 to lgN): (N / (interval / 2)) * (C * interval) = C * N/2 * Sigma(1..lgN) 1 = C * N * lgN /2
[ C is constant for accounting of inner sort(...) cost ]
I am printing out a list of prime numbers in a program and storing it an array. Then I want to get the the prime number on a particular index instead of the total list..
import java.util.*;
public class Gauss {
static int n;
static int[] array;
public static void Input() {
Scanner input = new Scanner(System.in);
System.out.println("Enter N: ");
n = input.nextInt();
}
public static boolean isPrime(int num) {
boolean prime = true;
int limit = (int) Math.sqrt(num);
for (int i = 2; i <= limit; i++) {
if (num % i == 0) {
prime = false;
break;
}
}
return prime;
}
public static void Calc() {
Input();
array = new int[1000];
for (int i = 2; i < array.length; i++) {
array[i] = i;
}
ArrayList<Integer> list = new ArrayList<Integer>(array.length);
for (int c : array) {
list.add(c);
}
list.remove(0);
list.remove(0);
Collections.sort(list);
for (int k : list) {
if (isPrime(k)) {
System.out.println(k);
}
}
}
public static void main(String[] args) {
Calc();
}
}
To get the nth prime just use array[n-1]
You might find this answer useful to a similar question.
And you can get the nth prime numbers with
List<Integer> primes = findPrimes(0, n);
System.out.println( primes.get(i) );
** EDIT **
Here is the integral test program that I came up (modified since the last posted answer above) with benchmark tests and all. I know there are faster implementations, and some optimizations can still be made, but here are some algorithms to generate prime numbers :
public class PrimeTests {
public static void main(String... args) {
AbstractPrimeGenerator[] generators = new AbstractPrimeGenerator[] {
new DefaultPrimeGenerator(),
new AtkinSievePrimeGenerator(),
new SundaramSievePrimeGenerator()
};
int[] primes;
int[] old_primes = null;
double[] testAvg = new double[generators.length];
long ts, te;
double time;
DecimalFormat df = new DecimalFormat("0.0######################");
int max = 10000000;
int testCountLoop = 10;
int it = 0, ti;
while (it++ < testCountLoop) {
ti = 0;
for (AbstractPrimeGenerator g : generators) {
ti++;
System.out.println(it + "." + ti + ". Calculating " + max
+ " primes numbers from " + g.getName() + "...");
ts = System.nanoTime();
primes = g.findPrimes(max);
te = System.nanoTime();
time = (te - ts) * Math.pow(10, -9) * 1000;
df.setRoundingMode(RoundingMode.HALF_UP);
testAvg[ti - 1] += time;
System.out.println("Found " + primes.length
+ " prime numbers (in " + time + " ms, "
+ df.format(time / primes.length) + " ms per prime)");
// for (int prime : primes) {
// System.out.print(prime + "... ");
// }
// System.out.println();
if (old_primes != null) {
System.out.print("Validating primes.... ");
if (primes.length == old_primes.length) {
for (int i = 0; i < primes.length; i++) {
if (primes[i] != old_primes[i]) {
System.out.println("Prime number does not match : " + primes[i] + " != " + old_primes[i] + " at index " + i);
System.exit(-1);
}
}
} else {
System.out.println("ERROR!! No match in prime results");
System.exit(-1);
}
System.out.println("Ok!");
}
old_primes = primes;
}
System.out.println("................");
}
System.out.println("Results:");
ti = 0;
for (AbstractPrimeGenerator g : generators) {
time = (testAvg[ti++] / testCountLoop);
System.out.println(ti + ". Average time finding " + max
+ " primes numbers from " + g.getName() + " = " + time
+ " ms or " + df.format(time / old_primes.length)
+ " ms per prime");
}
System.out.println("Done!");
}
/**
* Base class for a prime number generator
*/
static abstract public class AbstractPrimeGenerator {
/**
* The name of the generator
*
* #return String
*/
abstract public String getName();
/**
* Returns all the prime numbers where (2 <= p <= max)
*
* #param max
* int the maximum value to test for a prime
* #return int[] an array of prime numbers
*/
abstract public int[] findPrimes(int max);
}
/**
* Default naive prime number generator. Based on the assumption that any
* prime n is not divisible by any other prime m < n (or more precisely m <=
* sqrt(n))
*/
static public class DefaultPrimeGenerator extends AbstractPrimeGenerator {
#Override
public String getName() {
return "Default generator";
}
#Override
public int[] findPrimes(int max) {
int[] primes = new int[max];
int found = 0;
boolean isPrime;
// initial prime
if (max > 2) {
primes[found++] = 2;
for (int x = 3; x <= max; x += 2) {
isPrime = true; // prove it's not prime
for (int i = 0; i < found; i++) {
isPrime = x % primes[i] != 0; // x is not prime if it is
// divisible by p[i]
if (!isPrime || primes[i] * primes[i] > x) {
break;
}
}
if (isPrime) {
primes[found++] = x; // add x to our prime numbers
}
}
}
return Arrays.copyOf(primes, found);
}
}
/**
* Sieve of Atkin prime number generator Implementation following the Sieve
* of Atkin to generate prime numbers
*
* #see http://en.wikipedia.org/wiki/Sieve_of_Atkin
*/
static public class AtkinSievePrimeGenerator extends AbstractPrimeGenerator {
#Override
public String getName() {
return "Sieve of Atkin generator";
}
#Override
public int[] findPrimes(int max) {
boolean[] isPrime = new boolean[max + 1];
double sqrt = Math.sqrt(max);
for (int x = 1; x <= sqrt; x++) {
for (int y = 1; y <= sqrt; y++) {
int n = 4 * x * x + y * y;
if (n <= max && (n % 12 == 1 || n % 12 == 5)) {
isPrime[n] = !isPrime[n];
}
n = 3 * x * x + y * y;
if (n <= max && (n % 12 == 7)) {
isPrime[n] = !isPrime[n];
}
n = 3 * x * x - y * y;
if (x > y && (n <= max) && (n % 12 == 11)) {
isPrime[n] = !isPrime[n];
}
}
}
for (int n = 5; n <= sqrt; n++) {
if (isPrime[n]) {
int s = n * n;
for (int k = s; k <= max; k += s) {
isPrime[k] = false;
}
}
}
int[] primes = new int[max];
int found = 0;
if (max > 2) {
primes[found++] = 2;
}
if (max > 3) {
primes[found++] = 3;
}
for (int n = 5; n <= max; n += 2) {
if (isPrime[n]) {
primes[found++] = n;
}
}
return Arrays.copyOf(primes, found);
}
}
/**
* Sieve of Sundaram prime number generator Implementation following the
* Sieve of Sundaram to generate prime numbers
*
* #see http://en.wikipedia.org/wiki/Sieve_of_Sundaram
*/
static public class SundaramSievePrimeGenerator extends
AbstractPrimeGenerator {
#Override
public String getName() {
return "Sieve of Sundaram generator";
}
#Override
public int[] findPrimes(int max) {
int n = max / 2;
boolean[] isPrime = new boolean[max];
Arrays.fill(isPrime, true);
for (int i = 1; i < n; i++) {
for (int j = i; j <= (n - i) / (2 * i + 1); j++) {
isPrime[i + j + 2 * i * j] = false;
}
}
int[] primes = new int[max];
int found = 0;
if (max > 2) {
primes[found++] = 2;
}
for (int i = 1; i < n; i++) {
if (isPrime[i]) {
primes[found++] = i * 2 + 1;
}
}
return Arrays.copyOf(primes, found);
}
}
}
On my machine, the result gives :
Results:
1. Average time finding 10000000 primes numbers from Default generator = 1108.7848961000002 ms or 0.0016684019448402676 ms per prime
2. Average time finding 10000000 primes numbers from Sieve of Atkin generator = 199.8792727 ms or 0.0003007607413114167 ms per prime
3. Average time finding 10000000 primes numbers from Sieve of Sundaram generator = 132.6467922 ms or 0.00019959522073372766 ms per prime
Using one of the class's method above (you don't need the actual base class and all, only the actual method), you can do :
public class PrimeTest2 {
static public int[] findPrimes(int max) {
int[] primes = new int[max];
int found = 0;
boolean isPrime;
// initial prime
if (max > 2) {
primes[found++] = 2;
for (int x = 3; x <= max; x += 2) {
isPrime = true; // prove it's not prime
for (int i = 0; i < found; i++) {
isPrime = x % primes[i] != 0; // x is not prime if it is
// divisible by p[i]
if (!isPrime || primes[i] * primes[i] > x) {
break;
}
}
if (isPrime) {
primes[found++] = x; // add x to our prime numbers
}
}
}
return Arrays.copyOf(primes, found);
}
public static void main(String... args) {
Scanner input = new Scanner(System.in);
int MAX_N = Integer.MAX_VALUE / 100;
int n = 0;
while (n <= 0 || n >= MAX_N) {
System.out.print("Enter N: ");
n = input.nextInt();
if (n <= 0) {
System.out.println("n must be greater than 0");
}
if (n >= MAX_N) {
System.out.println("n must be smaller than " + MAX_N);
}
}
int max = n * 100; // just find enough prime numbers....
int[] primes = findPrimes(max);
System.out.println("Number of prime numbers found from " + 0 + " to "
+ max + " = " + primes.length);
System.out.println("The " + n
+ (n == 1 ? "st" : n == 2 ? "nd" : n == 3 ? "rd" : "th")
+ " prime number is : " + primes[n - 1]);
}
}
Which will output (for example) :
Enter N: 10000
Number of prime numbers found from 0 to 1000000 = 78498
The 10000th prime number is : 104729
With that in hand, you pretty have all that is to say about finding the nth prime number. For larger numbers (beyond int's), you'll have to modify the "default generator's" un-optimized method to accept long or use other methodologies (i.e. other language and/or libraries)
Cheers!
The code you have is pretty much the way to go, and Roflcopter's answer for picking the number is correct, but there is one optimization you could do that would significantly increase the performance. Instead of dividing by all numbers less than or equal to the square root, divide only by PRIMES less than or equal to the square root. Any number not divisible by any prime you've found so far is also not divisible by any combination of same, which is the definition of a nonprime number (having a prime factorization other than 1*N)