Random Prime Methods by calling another method - java

I am having a difficult time trying to figure out this program. I have made a method to find out if the number entered is a prime number but now I have to write a method that that takes a positive int num as it's parameter and returns a random prime number in the range of [0, num-1]. I'm not sure if I am using the isPrime method correctly. Also I have to test this method by calling it in the main but I'm not sure as how to do that as well. Here is my code:
public static boolean isPrime(int num)
{
for(int i = 2; i<= num-1;i++)
{
if (num % i == 0)
{
return false;
}
}
return true;
}
public static int randomPrime(int num)
{
Random r = new Random();
int x = r.nextInt(num);
for( int i = 0; i <= x; i++)
{
if(!isPrime(x))
{
num = x;
}
}
return x;
}

This is not an efficient way to do it. I would recommend you to construct an Eratosthene sieve and then select a random item of it.
Here is how I would do it :
public static Random rd = new Random(System.currentTimeMillis());
public static int randomPrime(int num) {
Boolean[] sieve = new Boolean[num+1];
sieve[0] = true;
sieve[1] = true;
for (int i=2 ; i<num.length ; i++)
if (!sieve[i])
for (int j = 2*i ; j<num.length ; j += i)
sieve[j] = true;
List<Integer> primes = new LinkedList<>();
for (int i=0 ; i<sieve.length ; i++)
if (!sieve[i]) primes.add(i);
return primes.isEmpty() ? -1 : primes.get(rd.nextInt(primes.size());
}

If you are checking to see if x is prime in your randomPrime method, why are you calling isPrime on 0 <= i <= x? You are checking if any number between (inclusive) 0 and x is prime. That is not what you want.
I think this should do the trick for you without a drastic change of algorithm. Note: This code may take an exceedingly long time to terminate based on your random number generator and seed value and is not actually guaranteed to terminate. (Consider the case where your random number generator only produces composite numbers.)
public static int randomPrime(int num)
{
Random r = new Random();
int x = r.nextInt(num);
while(!isPrime(x))
{
x = r.nextInt(num);
}
return x;
}
Update:
Test it with something like this:
public static void main(String[] args)
{
int N = 42;
int x = randomPrime(N);
System.out.println(x);
}

Related

How to find prime numbers in an array of random numbers?

I have a problem with finding prime numbers in an array of randomly generated integers.
I tried using the 'for' loop to go through every element in my array to check whether it's a prime number or not. Although it prints some ints from the array, they are not prime numbers.
public static void main(String[] args) {
defineTable();
printPrimeNumbers();
}
private static int[] tab;
private static int[] defineTable(){
tab = new int[100];
for (int i = 0; i < tab.length; i++){
tab[i] = randomFill();
}
return tab;
}
private static int randomFill (){
Random rand = new Random();
int randomInt = rand.nextInt();
return randomInt;
}
private static void printPrimeNumbers(){
boolean isPrime = true;
for (int i = 0; i < tab.length; i++){
int num = tab[i];
for (int j = 2; j < num; j++){
if (num % j == 0){
isPrime = false;
break;
}
}
if(isPrime){
System.out.println(num + " jest liczbą pierwszą.");
}
}
}
Any solutions to this problem? I started learning Java 4 days ago on my own. So far everything goes well, I understand most of the basics. But this problem seems too complex for me, a beginner.
Edit: I translated most of the code's variables to English from Polish, as my native language is Polish, hope it's understandable.
You're only setting isPrime to true at the beginning of printPrimeNumbers. Once it finds the first composite number, it becomes false, and you never reset it to true again to test the next number.
when writing Java code, try to split the task into functions(should serve a single purpose only). For your code extract the logic of determining Prime into a separate method and pass the random number to check whether it's prime or not, if yes then print otherwise don't print or do nothing.
Please check the below code snippet
A simpler and efficient way to find the prime number
public static boolean isPrime(int n) {
if (n <= 1) {
return false;
}
for (int i = 2; i <= Math.sqrt(n); i++) {
if (n % i == 0) {
return false;
}
}
return true;
}
private static void printPrimeNumbers(){
for (int i = 0; i < tab.length; i++){
if(isPrime(tab[i])){
System.out.println(tab[i] + " jest liczbą pierwszą.");
}
}

prime factorization decryption

I have a program that is supposed to decrypt a number to its primes. The primes also have an order: for instance, 2 is the 1st prime number, 3 is the second 5 is the third and so on. The indexes are 1 is for a, two is for b, three is for c and so on. I don't know how to compare the two array lists in order to assign an index to each prime so I can decode a word which is encrypted in the number 72216017. The number 72216017 has the primes 17,19,47,67,71. If 2,3,5,7,11... are a,b,c,d,e... these five prime numbers make up the word ghost, I just don't know how to assign and sort these numbers by their index.
package name;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
public class PrimeFactorsEffective {
private static int z;
private int w = z;
public static List<Integer> primeFactors(int numbers) {
int n = numbers;
List<Integer> factors = new ArrayList<Integer>();
for (int i = 2; i <= n / i; i++) {
while (n % i == 0) {
factors.add(i);
n /= i;
}
if (n > 1) {
factors.add(n);
System.out.println(factors);
z = Collections.max(factors);
}
}
return factors;
}
public static void main(String[] args) {
System.out.println("Primefactors of 72216017");
for (Integer integer : primeFactors(72216017)) {
System.out.println(integer);
}
List<Integer> factors1 = new ArrayList<Integer>();
List<String> index1 = new ArrayList<String>();
int i;
int element = 0;
int num = 0;
int maxCheck = z; // maxCheck limit till which you want to find prime numbers
boolean isPrime = true;
String primeNumbersFound = "";
//Start loop 1 to maxCheck
for (i = 1; i <= maxCheck; i++) {
isPrime = CheckPrime(i);
if (isPrime) {
primeNumbersFound = primeNumbersFound + i + " ";
factors1.add(i);
factors1.get(num);
}
}
System.out.println("Prime numbers from 1 to " + maxCheck + " are:");
System.out.println(factors1);
}
public static boolean CheckPrime(int numberToCheck) {
int remainder;
for (int i = 2; i <= numberToCheck / 2; i++) {
remainder = numberToCheck % i;
if (remainder == 0) {
return false;
}
}
return true;
}
}
You can store the primes in a List (primes in this list will be in increasing order). Now you can use Collections.BinarySearch to get the index of the prime for which you wan to find the corresponding alphabet. Once you got the index (index here according to you starts from 1, so a's index is 1, b's index is 2, c's index is 3 and so on) you can do simply something like char currentCharacter = (char) ('a' + primeIndex - 1) and the variable currentCharacter will store the alphabet corresponding to primeIndex.
Some other minor things that I'd like to suggest:
Which checking whether a number is prime or not, you can simply check upto square-root of numberToCheck. So you can replace your loop for (int i = 2; i <= numberToCheck / 2; i++) to for (int i = 2; i*i <= numberToCheck; i++). Note that It is not a good idea to calculate square-root using Math.sqrt, instead you can have a condition like i*i <= numberToCheck.
Please refrain from naming your packages that seem to be random.
As of Java SE 7 explicit type-arguments while initializing the list are not required. You can replace List<Integer> factors1 = new ArrayList<Integer>() with List<Integer> factors1 = new ArrayList<>(). Please read this for more information.
Your factor method don't really look good to me, it don't give correct results. Please see the following method that gives correct result:
{{
public static List<Integer> primeFactors(int numbers) {
int n = numbers;
List<Integer> factors = new ArrayList<>();
for (int i = 2; n>1; i++) {
while (n % i == 0) {
factors.add(i);
n /= i;
}
}
z = Collections.max(factors);
return factors;
}

Printing Prime Numbers to N value

This program is supposed to print all the prime numbers up to an int that you enter, for example:
Enter a Number:
20
2
3
5
7
11
13
17
19
I just cannot get my program to work, I really don't know what to do, so if someone could review it and try to fix it, that would be greatly appreciated, thanks.
import java.util.Scanner;
public class PrimeGenerator {
public static void main(String args[]) {
Scanner k = new Scanner(System.in);
System.out.println("Enter an integer");
int number = k.nextInt();
PrimeGenerator matt = new PrimeGenerator();
System.out.println(matt.nextPrime(number));
}
private int number;
public PrimeGenerator(int n) {
number = n;
}
public int nextPrime(int number) {
for (int i = 1; i <= number; i++) {
boolean prime = true;
for (int j = 2; j < i; j++) {
if (i % j == 0) {
prime = false;
}
}
if (prime){
return i;
}
}
}
}
You're already there actually. You've just got a mistake in the program-flow.
for (int i = 1; i <= number; i++) {
boolean prime = true;
for (int j = 2; j < i; j++) {
if (i % j == 0) {
prime = false;
}
}
if (prime){
return i; //<-- this return will terminate nextPrim
}
}
Things to fix/improve:
nextPrim would need to return a value within every possible program-branch. This means: consider the case where nextPrim doesn't find any number in the given range and steps out of the loop. Now the program would be stuck without any return-value.
Instead of returning the first prim-number found, you could print that found prim-number and keep the generator running. Nice, easy and solves the hassle with returning anything, since you now can simply declare nextPrim as void. I'd recommend renaming it to printPrims or something like that to make this change clear.
Passing number: You can save a bit of effort by only passing number once to the prim-generator. The simplest solution would be to pass it to nextPrim/printPrims. Now you can remove the instance-variable number and the constructor, which solves the issue with th e signature of the constructor.
1 is not a prim-number to be pedantic. So let's be pedantic and start the outer loop in printPrims with 2, so that 2 will be the first number that is checked for being a prim.
So let's put this into code:
import java.util.Scanner;
public class PrimeGenerator {
public static void main(String args[]) {
Scanner k = new Scanner(System.in);
System.out.println("Enter an integer");
int number = k.nextInt();
PrimeGenerator matt = new PrimeGenerator();
matt.printPrims(number);
}
public void printPrime(int number) {
for (int i = 2; i <= number; i++) {
boolean prime = true;
for (int j = 2; j < i; j++) {
if (i % j == 0) {
prime = false;
}
}
if (prime){
System.out.println(i);
}
}
}
A few general hints:
Work through compiler errors. They tell you precisely where and what errors occur within your code.
Think about the flow of your program before even implementing it.
Break the task down into smaller tasks and implement these one after another. As an example: for this problem first print out all numbers in the range 2, number. Afterwards go a step further and add functionality to filter out prim-numbers. Now you've got two components that you can easily test independent of each other.
You were nearly there but your nextPrimes function was terminating prematurely when you returned i, try something like this:
import java.util.Scanner;
class Main {
public static void main(String[] args) {
Scanner k = new Scanner(System.in);
System.out.print("Enter an integer:");
int number = k.nextInt();
printPrimesUptoN(number);
}
public static void printPrimesUptoN(int n){
for(int i=2;i<n;i++){
boolean isPrime = true;
for(int j=2;j<i;j++){
if(i % j == 0){
isPrime = false;
break;
}
}
if(isPrime)
System.out.println(i);
}
}
}
Try it here!
There's a few issues with your code, maybe we can fix it together. First things first, you're missing a return statement in nextPrime and there's no empty default constructor PrimeGenerator() because you created a single-arg constructor. Try this:
public class PrimeGenerator {
public static void main(String args[]) {
Scanner k = new Scanner(System.in);
System.out.println("Enter an integer");
int number = k.nextInt();
// you probably want to pass your maximum value to the constructor
PrimeGenerator matt = new PrimeGenerator(number);
// without a loop of some sort this will only print a single prime number, e.g.
// Enter a Number:
// 20
// 2
System.out.println(matt.nextPrime(number));
}
private int number;
public PrimeGenerator(int n) {
this.number = n;
}
// you're using the argument as upper boundary for your prime detection while not increasing your lower boundary
// also you're checking if i is a prime here which you always start at 1. this should always return the same value because once you find a prime number you return
// you should consider using an algorithm like Sieve of Eratosthenes (or advanced verions thereof) to determine if a given number is prime
public int nextPrime(int number) {
for (int i = 1; i <= number; i++) {
boolean prime = true;
for (int j = 2; j < i; j++) {
if (i % j == 0) {
prime = false;
}
}
if (prime){
return i;
}
}
// you need to return something at the end of this method or throw an exception
throw new IllegalStateException("no more prime numbers available!");
}
}
This is not a solution which will yield the results you're expecting but it will compile at least. From that point you can move forward and fix the algorithmic issues.
Your original error was in.
PrimeGenerator matt = new PrimeGenerator();
Error:
PrimeGenerator.java:7: error: constructor PrimeGenerator in class PrimeGenerator cannot be applied to given types;
PrimeGenerator matt = new PrimeGenerator();
^
required: int
found: no arguments
reason: actual and formal argument lists differ in length
1 error
Notice that you had a method with the same name as you class, but I don't think you were using it as a constructor and if you were it took an int which you didn't give it. Your method on line 13 was:
public PrimeGenerator(int n) {
number = n;
}
Try doing
new PrimeGenerator().nextPrime(number);
Instead
import java.util.Scanner;
public class PrimeGenerator {
public static void main(String args[]) {
Scanner k = new Scanner(System.in);
System.out.println("Enter an integer");
int number = k.nextInt();
new PrimeGenerator().nextPrime(number);
}
public void nextPrime(int number) {
for (int i = 1; i <= number; i++) {
boolean prime = true;
for (int j = 2; j < i; j++) {
if (i % j == 0) {
prime = false;
}
}
if (prime){
System.out.println(i);
}
}
}
}
Optionally, to use your original constructor, you could separate this out.
import java.util.Scanner;
public class PrimeGenerator {
private int number;
public static void main(String args[]) {
Scanner k = new Scanner(System.in);
System.out.println("Enter an integer");
int number = k.nextInt();
// Initialize with a number.
PrimeGenerator pg = new PrimeGenerator(number);
pg.printPrimes();
}
// This is the constructer you were misusing.
public PrimeGenerator(int n) {
number = n;
}
public void printPrimes() {
// Actually use your private number variable.
for (int i = 1; i <= number; i++) {
boolean prime = true;
for (int j = 2; j < i; j++) {
if (i % j == 0) {
prime = false;
}
}
if (prime){
System.out.println(i);
}
}
}
}
There are several issues:
Are you using an IDE? If so, which is it, else Why not?. If you consider yourself a beginner, be advised to used one, like Eclipse IDE or NetBeans IDE.
Regarding to your algorithm, at first glance, there is a compilation and a logic problems.
Compilation problem is when the execution of your class not work. In this case the method nextPrime(int number) MUST return an int. Although you put return clause, the method is not returning any value when prime is false. You could easily spot this problem with an IDE.
Another compilation problem, the sentinel or variable i is INSIDE the for loop, and you are printing it's value OUTSIDE of it. Once again, the IDE would help you with this problem.
Logic problem is, you are returning a value if and only if the flag prime is true, so, when calling the method (supposing is working) you only obtain ONE value when you call System.out.println(matt.nextPrime(number));
The correct implementation would have these considerations:
The method doesn't return, i.e public void nextPrime(number) { ..., which means you don't need print in the main method, just call it.
The method actually prints the numbers.
In this way, you can check if i % j is different of zero, then you don't need to process more dividers, breaking the for loop.
Print it.
That's it.
public static void main(String [] args) {
.
.
.
PrimeGenerator matt = new PrimeGenerator();
matt.nextPrime(number);
}
public void printPrime(int number) {
boolean prime = true;
for (int i = 2; i <= number; i++) {
prime = true;
for (int j = 2; j < i; j++) {
if (i % j != 0) {
prime = false;
break;
}
}
if (prime) {
System.out.println(i);
}
}
}

How to generate huge amount of prime numbers in java?

In order to solve a question I have to generate a list of prime numbers from 1 to 3000000, so I tried several ways to do this and unfortunately all failed...
First try: because all prime numbers bigger than 2 are odd numbers, so I first generate a list of odd numbers started with 3 called allOddNums. And then I generate a list of all composite numbers called allComposite. Then I remove all the number in allComposite from allOddNums to obtain prime numbers. Here is my code:
/** Prime Numbers Generation
* Tony
*/
import java.util.*;
public class PrimeNumG {
public static void main(String[] args) {
List <Long> allOddNums = new ArrayList<Long>();
for (long i = 3; i < 200; i += 2) {
allOddNums.add(i);
}
// composite number generator:
List <Long> allComposite = new ArrayList<Long>();
for (long a = 2; a < Math.round(Math.sqrt(3000000)); a += 2) {
for (long b = 2; b < Math.round(Math.sqrt(3000000)); b += 2) {
allComposite.add(a*b);
}
}
// remove duplicated:
Set <Long> hs = new HashSet<Long>();
hs.addAll(allComposite);
allComposite.clear();
allComposite.addAll(hs);
// remove all composite from allRealNums = allPrime
allOddNums.removeAll(allComposite);
allOddNums.add(0, (long)2);
System.out.printf("%s ", allOddNums);
Scanner sc = new Scanner(System.in);
int times = sc.nextInt();
for (int i = 0; i < times; i++) {
int index = sc.nextInt();
System.out.print(allOddNums.get(index) + " ");
}
}
}
In this case, when I need to generate a few prime numbers it works fine. However, if I want to generate until 3000000 it fails me(used up memory).
Second try: I searched online and find an algorithm called sieve of Eratosthenes. then I first generate 2, 3, 5, 7, 9...(all odd numbers + 2), then I remove every 3rd number after 3 and every 5th number after 5. The code is as below:
/** Prime Number Generator
* Tony
*/
import java.util.*;
public class Solution61 {
public static void main(String[] args) {
List<Long> l1 = new ArrayList<Long> ();
// l1 generator: 3 5 7 9 11 ...
for (long d = 3; d < 100; d += 2) {
l1.add(d);
}
l1.add(1, (long)2); // 2 3 5 ...
removeThird(l1); // rm 3rd after 3
removeFifth(l1); // rm 5th after 5, now the l1 will be prime number
Scanner sc = new Scanner(System.in);
int times = sc.nextInt();
for (int i = 0; i < times; i++) {
int index = sc.nextInt();
System.out.print(l1.get(index) + " ");
}
}
/** removeThird : remove every 3rd number after 3
* param List | return void
*/
private static void removeThird(List<Long> l) {
int i = 1;
int count = 0;
while (true) {
if (count == 3) {
l.remove(i);
count = 1;
}
i ++;
count ++;
if (i > l.size()) {
break;
}
}
}
/** removeThird : remove every 5th number after 5
* param List | return void
*/
private static void removeFifth(List<Long> l) {
int i = 2;
int count = 0;
while (true) {
if (count == 5) {
l.remove(i);
count = 1;
}
i ++;
count ++;
if (i > l.size()) {
break;
}
}
}
}
This is still not up to the task because it also runs out of memory.
3rd try:
I tried to generate from 1 to the 3000000, and then remove every number is the product of prime number and another number. The code is as below:
/** print all the prime numbers less than N
* Tony
*/
public class primeGenerator {
public static void main(String[] args) {
int n = 3000000;
boolean[] isPrime = new boolean[n];
isPrime[0] = false; // because 1 is not a prime number
for (int i = 1; i < n; i++) {
isPrime[i] = true;
} // we set 2,3,4,5,6...to true
// the real number is always (the index of boolean + 1)
for (int i = 2; i <= n; i++) {
if (isPrime[i-1]) {
System.out.println(i);
for (int j = i * i; j < n; j += i /* because j is determined by i, so the third parameter doesn't mater*/) {
isPrime[j-1] = false;
}
}
}
}
}
it still fails me, well guess 3000000 is really a big number huh? Is there any simple and brilliant rookie-friendly way to generate prime numbers below 3000000? Thx!
fourth try:
#jsheeran Is this code below what your answer means? when I hit 1093 it gets slower and slower and my IDE still crashed. Plz tell me if I misinterprete your approach, thx!
/** new approach to find prime numbers
* Tony
*/
import java.util.*;
public class PrimeG {
/** isPrime
* To determine whether a number is prime by dividing the candidate number by each prime in that list
*/
static List<Long> primes = new ArrayList<Long> ();
private static void isPrime(long n) {
boolean condition = true;
for (int i = 0; i < primes.size(); i++) {
if (n % primes.get(i) == 0) {
condition = condition && false;
}
}
if (condition) {
findNextPrime(n);
}
}
/** findNextPrime
* expand the list of prime numbers
*/
private static void findNextPrime(long n) {
primes.add(n);
}
public static void main(String[] args) {
primes.add((long)2);
primes.add((long)3);
primes.add((long)5);
primes.add((long)7);
for (int i = 8; i < 3000000; i++) {
isPrime(i);
System.out.printf("%s", primes);
}
}
}
Fixed implementation of Sieve of Eratosthenes (your third try). I believe it should satisfy your needs.
public static void main (String[] args) throws java.lang.Exception {
int n = 3000000;
boolean[] isPrime = new boolean[n+1];
for (int i = 2; i <= n; i++) {
isPrime[i] = true;
}
for (int factor = 2; factor*factor <= n; factor++) {
if (isPrime[factor]) {
for (int j = factor; factor*j <= n; j++) {
isPrime[factor*j] = false;
}
}
}
for (int i = 2; i <= n; i++) {
if (isPrime[i]) System.out.println(i);
}
}
An alternative approach would be to begin with a list of primes consisting of 2 and 3. Have a method isPrime(int) to determine whether a number is prime by dividing the candidate number by each prime in that list. Define another method, findNextPrime(), which isPrime() can call to expand the list as needed. This approach has far lower overhead than maintaining lists of all odd and composite numbers.
Memory is not an issue in your case. Array of size n = 3000000 can be defined inside the stack frame of a function. Actually array of size 10^8 can be defined safely inside a function. If you need more than that define it as a gloabal variable(Instance variable). Coming to your code there is an IndexOutOfBoundsException in your third code. You need to check for factors of a number only uptill sqrt(n). Factors exist in pairs one factor <=sqrt(n) and other >=sqrt(n). So you can optimize the sieve of Eratosthenes algorithm. Here is a link to one wonderful tutorial on various optimizations of sieve.
This can generate prime numbers up to Integer.MAX_VALUE in few milliseconds. It also doesn't take as much memory as in Sieve of Eratosthenes approach.
public class Prime {
public static IntStream generate(int limit) {
return IntStream.range(2, Integer.MAX_VALUE).filter(Prime::isPrime).limit(limit);
}
private static boolean isPrime(int n) {
return IntStream.rangeClosed(2, (int) Math.sqrt(n)).noneMatch(i -> n % i == 0);
}
}

Next Prime number Java only working with certain numbers

This function its only working for certain numbers, but for 15, or 5 it does not give me correct next prime.
public static int nextPrime(int n) {
boolean isPrime = false;
int m = (int) Math.ceil(Math.sqrt(n));
int start = 3;
if (n % 2 == 0) {
n = n + 1;
}
while (!isPrime) {
isPrime = true;
for (int i = start; i <= m; i = i + 2) {
if (n % i == 0) {
isPrime = false;
break;
}
}
if (!isPrime) {
n = n + 2;
}
}
return n;
}
You don't need to go upto sqrt(n), you need to go upto sqrt(number) that you are evaluating
for example consider you pass n = 5
it will start loop from 3 and it will end the loop at 4 that is not what you need to find next prime number
outer loop
start from n + 1 until you find prime
inner loop
you should start from 3 and sqrt(numberUnderIteration)
You're setting your boundary at the square root of the original number only. In order for you to check if every next number works, you need to recalculate the boundary whenever the n value is changed. So, put int m = (int) Math.ceil(Math.sqrt(n)); inside of your while loop.
You also need to increment n by 1 before you start any calculations, or it will accept n itself as a prime number if it is one. For example, nextPrime(5) would return 5 because it passes the conditions.
And finally, you don't need to increment n by 2 at the end of your while loop because if you are on an even number, it will break out (keep adding 2 to an even number will always be even). I've commented the part of your code that I changed:
public static int nextPrime(int n) {
boolean isPrime = false;
int start = 2; // start at 2 and omit your if statement
while (!isPrime) {
// always incrememnt n at the beginning to check a new number
n += 1;
// redefine max boundary here
int m = (int) Math.ceil(Math.sqrt(n));
isPrime = true;
// increment i by 1, not 2 (you're skipping numbers...)
for (int i = start; i <= m; i++) {
if (n % i == 0) {
isPrime = false;
break;
}
}
// you don't need your "if (!isPrime)..." because you always increment
}
return n;
}
public static void main(String[] args) {
System.out.println(nextPrime(15)); // 17
System.out.println(nextPrime(5)); // 7
System.out.println(nextPrime(8)); // 11
}
You need to compute m inside the for loop.
while (!isPrime) {
isPrime = true;
int m = (int) Math.ceil(Math.sqrt(n));
// do other stuff
Your code works fine except when a prime number is given as input, your method returns input itself.
Example if 5 is your input nextPrime(5) returns 5. If you want 7 (next prime number after 5) to be returned in this case.
Just add n=n+1; at the start of your method. Hope this helps
Just for fun, I coded a quick Prime class that tracks known primes, giving a huge performance boost to finding multiple large primes.
import java.util.ArrayList;
public class Primes {
private static ArrayList<Integer> primes = new ArrayList<Integer>();
public static int nextPrime(int number){
//start it off with the basic primes
if(primes.size() == 0){
primes.add(2);
primes.add(3);
primes.add(5);
primes.add(7);
}
int idx = primes.size()-1;
int last = primes.get(idx);
//check if we already have the prime we are looking for
if(last > number){
//go to the correct prime and return it
boolean high = false;
boolean low = false;
int prevIdx = 0;
int spread = 0;
//keep finagling the index until we're not high or low
while((high = primes.get(idx-1) > number) || (low = primes.get(idx) <= number)){
spread = Math.abs(prevIdx-idx);
//because we always need to move by at least 1 or we will get stuck
spread = spread < 2 ? 2: spread;
prevIdx = idx;
if(high){
idx -= spread/2;
} else if(low){
idx += spread/2;
}
};
return primes.get(idx);
}
/*FIND OUR NEXT SERIES OF PRIMES*/
//just in case 'number' was prime
number++;
int newPrime = last;
//just keep adding primes until we find the right one
while((last = primes.get(primes.size()-1)) < number){
//here we find the next number
newPrime += 2;
//start with the assumption that we have a prime, then try to disprove that
boolean isPrime = true;
idx = 0;
int comparisonPrime;
int sqrt = (int) Math.sqrt(newPrime);
//make sure we haven't gone over the square root limit- also use post-increment so that we use the idx 0
while((comparisonPrime = primes.get(idx++)) <= sqrt){
if(newPrime % comparisonPrime == 0){
isPrime = false;
}
}
if(isPrime){
primes.add(newPrime);
}
}
return last;
}
}
And here is the test:
public class Test {
public static void main(String[] args){
long start;
long end;
int prime;
int number;
number = 1000000;
start = System.currentTimeMillis();
prime = Primes.nextPrime(number);
end = System.currentTimeMillis();
System.out.println("Prime after "+number+" is "+prime+". Took "+(end-start)+" milliseconds.");
number = 500;
start = System.currentTimeMillis();
prime = Primes.nextPrime(number);
end = System.currentTimeMillis();
System.out.println("Prime after "+number+" is "+prime+". Took "+(end-start)+" milliseconds.");
number = 1100000;
start = System.currentTimeMillis();
prime = Primes.nextPrime(number);
end = System.currentTimeMillis();
System.out.println("Prime after "+number+" is "+prime+". Took "+(end-start)+" milliseconds.");
}
}
This results in the following output:
Prime after 1000000 is 1000003. Took 384 milliseconds.
Prime after 500 is 503. Took 10 milliseconds.
Prime after 1100000 is 1100009. Took 65 milliseconds.
As you can see, this takes a long time the first iteration, but we only have to perform that operation once. After that, our time is cut down to almost nothing for primes less than our first number (since it's just a lookup), and it is very fast for primes that are just a bit bigger than our first one (since we have already done most of the work).
EDIT: Updated search for existing primes using a variation on a Binary Search Algorithm. It cut the search time at least in half.
import java.util.Scanner;
class Testing
{
public static void main(String Ar[])
{
int a = 0, i, j;
Scanner in = new Scanner(System.in);
a = in.nextInt();
for (j = a + 1;; j++)
{
for (i = 2; i < j; i++)
{
if (j % i == 0)
break;
}
if (i == j)
{
System.out.println(j);
break;
}
}
}
}
Here is the perfect code for finding next prime for a given number.
public class NextPrime
{
int nextPrime(int x)
{
int num=x,j;
for( j=num+1;;j++)
{
int count=0;
for(int i=1;i<=j;i++)
{
if(j%i==0)
{
count++;
//System.out.println("entered");
}
//System.out.println(count);
}
if(count==2)
{
System.out.println(" next prime is ");
break;
}
}return j;
}
public static void main(String args[])
{
NextPrime np = new NextPrime();
int nxtprm = np.nextPrime(9);
System.out.println(nxtprm);
}
}
//I hope the following code works exactly.
import java.util.Scanner;
public class NextPrime {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
System.out.println("Enter a positive integer number : ");
int n = scanner.nextInt();
for (int x = n + 1;; x++) {
boolean isPrime = true;
for (int i = 2; i < x / 2; i++) {
if (x % i == 0) {
isPrime = false;
break;
}
}
if (isPrime) {
System.out.println("Next prime is : " + x);
break;
}
}
}
}

Categories

Resources