Prime Number Program Problems - java

I'm currently working on a program in which the user inputs a number, and the program will give you the number of prime numbers up to that number. Although there are no errors, the program always outputs the same number: 3. This is the code:
public static int Prime(int num){
boolean isPrime = true;
int count = 0;
for (int a = 2; a <=num; a++){
for (int i = 2; i <= a/2; i++){
if (a == 2 || a == 3 || a == 5){
isPrime = true;
}
else if (a % i == 0){
isPrime = false;
}
}
if (isPrime == true)
count++;
}
return count;
}

In your inner for loop, you are setting isPrime, but then you keep looping. Subsequent loops may set isPrime to false if a candidate divisor i doesn't divide cleanly. Only 2, 3, and 5, the 3 numbers in your first if condition, set it to true always, so you always get 3.
Instead, set isPrime to true at the beginning of the inner for loop, and break out of the inner for loop after each time you set isPrime. If the number is 2, 3, or 5, set to true and break so nothing can set it to false, so you can count it. If you found a factor, it's not prime, so set to false and break so nothing can set it to true and it's not counted.
Incidentally, your final if condition tests a boolean; it can be simplified to if (isPrime).

Your strategy is to test each number from 2 through num for primality by scanning for factors other than itself and 1. That's ok, albeit a bit simplisitic, but your implementation is seriously broken.
An approach involving scanning for factors implies that you start by guessing that the number being tested is prime, and then go looking for evidence that it isn't. You've missed the "guessing it's prime" part, which in your particular code would take the form of setting isPrime to true at the beginning of your outer loop.
Your code, on the other hand, never resets isPrime to true after testing the case of a == 5. That variable will be set to false when testing the case of a == 6, and will remain so for the duration. That is why you always get the result 3 for any input greater than 4.
If you properly reset isPrime in the outer loop then you can also remove the first part of the conditional in the inner loop, as it will be redundant. It is anyway never executed in the cases of a == 2 and a == 3 because the inner loop performs zero iterations in those cases.
Note also that it would be more efficient to break from the inner loop as soon as you determine that a is composite, and that you run more iterations of that loop than you need to do for primes (it would be sufficient to loop until i exceeds the square root of a; that is, until i * i > a).
Finally, note that this problem would be more efficiently implemented via the Seive of Eratosthenes (or one of the other prime number seives) as long as the numbers you want to test are not so large that the needed array would be prohibitively large.

I simplified your code by reducing number of operations which is needed to check if a is 2, 3, or 5.
public static int Prime(int num) {
int count = 0;
if (num >= 2) {
count++; // One optimization here
}
for (int a = 3; a <= num; a+=2) { // Another one here as we don't have any even number except 2 :D
boolean isPrime = true;
for (int i = 2; i <= a / 2; i++) {
if (a % i == 0) {
isPrime = false;
break;
}
}
if (isPrime) {
count++;
}
}
return count;
}

#include <iostream>
using namespace std;
int numberOfPrimes(int num)
{
if(num==2)
return 1;
else if(num<2)
return 0;
int prime=1;
for(int i=3;i<=num;i++)
{
for(int j=2;j<=(i/2)+1;j++)
{
if(i%j==0)
break;
if(j==(i/2)+1)
prime++;
}
}
return prime;
}

package com.amit.primenumber;
public class PrimeNumber {
public static void main(String[] args) {
long number=23L;
String message=null;
PrimeNumber primeNumber = new PrimeNumber();
boolean result = primeNumber.primeNumber(number);
if(result){
message="a Prime Number";
}else{
message="Not a Prime Number";
}
System.out.println("The given "+number+" number is "+message);
}
public boolean primeNumber(long number){
for(long i=2;i<=number/2;i++){
if(number%i==0){
return false;
}
}
return true;
}
}

package basics;
public class CheckPrimeOrNot {
public void checkprimeNumber(int i){
int flag=0;
if(i>2){
for(int j = 2; j <= i/2; j++){
if(i%j == 0){
System.out.println("Given number is Not Prime");
flag=1;
break;
}
}
if(flag==0){
System.out.println("Given number is Prime");
}
} else{
System.out.println("Please enter a valid number");
}
}
public static void main(String[] args) {
CheckPrimeOrNot CheckNumber = new CheckPrimeOrNot();
CheckNumber.checkprimeNumber(11);
CheckNumber.checkprimeNumber(0);
CheckNumber.checkprimeNumber(250365);
CheckNumber.checkprimeNumber(1231);
}
}

Related

Getting weird output while finding prime number in java

I have two methods to find out prime number in java method - 2 working fine but getting wrong output from method one, can any help me where i did wrong in logic. Thanks in advance
My entire code
package prepare;
import java.util.Scanner;
public class Squar {
//Method - 1 to find prime number
boolean isPrime(int num){
int exp = (int)Math.sqrt(num);
for(int i=2;i<exp;i++){
if(exp%2==0){
return false;
}
}return true;
}
public static void main(String[] args) {
Scanner scan = new Scanner(System.in);
int num = scan.nextInt();
Squar s = new Squar();
System.out.println("From M1 "+s.isPrime(num));
scan.close();
System.out.println("From M2 "+s.isPrimeNumber(num));
}
//Method - 2 to find prime number
public boolean isPrimeNumber(int number) {
if(number == 1){
return false;
}
if (number == 2 || number == 3) {
return true;
}
if (number % 2 == 0) {
return false;
}
int sqrt = (int) Math.sqrt(number) + 1;
for (int i = 3; i < sqrt; i += 2) {
if (number % i == 0) {
return false;
}
}
return true;
}
}
for input : 63 actual out put would be false in prime number but getting
different output from method one
output
63
From M1 true
From M2 false
In isPrime() method, Shouldn't you be checking num % i == 0 rather than exp % 2 == 0?
Change isPrime function like this.
boolean isPrime(int num) {
int exp = (int) Math.sqrt(num);
for (int i = 2; i < exp; i++) {
if (num % i == 0) {
return false;
}
}
return true;
}
Because in if condition you are checking exp%2 == 0 . But this statement does not change when iterating on i < exp. So this logic should be on with num % i == 0
Have a look at this line of your code
if(exp%2==0){
it should be num % i
Well I think the culprit is
if(exp%2==0){
and it is causing a problem while iterating i<exp.So you may want to tweak it to
num%i==0
I have tried to give a few other approaches to this issue.
I hope that would be helpful.
I think there is a reason that tempted you to use
(int)Math.sqrt(num);
I have tried to elaborate it below.
Consider below 3 approaches.
All of them are correct but the first 2 approaches have some drawbacks.
Approach 1
boolean isPrime(int num) {
for(int i=2;i<num;i++) {
if(num%i==0)
return false;
}
return true;
}
We have a scope to make it faster.
Consider that if 2 divides some integer n, then (n/2) divides n as well.
This tells us we don't have to try out all integers from 2 to n.
Now we can modify our algorithm:
Approach 2
//checks whether an int is prime or not.
boolean isPrime(int num) {
for(int i=2;2*i<num;i++) {
if(num%i==0)
return false;
}
return true;
}
Finally, we know 2 is the "oddest" prime - it happens to be the only even prime number.
Because of this, we need only check 2 separately, then traverse odd numbers up to the square root of n.
I think this might have tempted you to use (int)Math.sqrt(num);
Approach 3
//checks whether an int is prime or not.
boolean isPrime(int num) {
//check if num is a multiple of 2
if (num%2==0) return false;
//if not, then just check the odds
for(int i=3;i*i<=num;i+=2) {
if(num%i==0)
return false;
}
return true;
}
Hence, we've gone from checking every integer (up to n to find out that a number is prime) to just checking half of the integers up
to the square root.
Is it not an improvement, especially considering when numbers are large.
Well, your first algorithm is almost (replace %2 with %i) correct. I do not know the second algorithm, but i would definitely change it to this form:
public 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;
}

Why does it matter if I declare a boolean outside vs. inside this while loop?

public class FindPrimes {
public static void main(String[] args) {
int Number_of_prime = 50;
int number_of_final = 10;
int count = 0;
int number = 2;
boolean isPrime = true;
while (count < Number_of_prime) {
for (int divisor = 2; divisor <= number / 2; divisor++) {
if (number % divisor == 0) {
isPrime = false;
break;
}
}
if (isPrime) {
count++;
if (count % number_of_final == 0)
System.out.println(number);
else
System.out.print(number + " ");
}
number++;
}
}
}
The program should find the first 50 prime numbers. When I declare boolean isPrime outside of the while loop (example above) I only get the primes 2 and 3, but when I declare boolean isPrime inside the while loop, I get all 50 prime numbers.
Why is this happening?
I am assuming that you're getting the right answer but you're not sure how/why it is.
Declaring isPrime outside of while does not work. Why? Because if you don't find a prime number within the loop, you set isPrime to false ...and you never reset it back to true ever again. Therefore, any subsequent numbers that come after the non-prime number would automatically default to a non-prime number.
Declaring isPrime inside of while works. Why? Because everytime you find a prime OR non-prime number, you will reset isPrime back to its original value and every subsequent number can and will be evaluated for its prime-ness accordingly.
Try drawing it out if you still have trouble understanding.
Hope that helps.

Prime numbers finder

So I'm trying to make a method that finds a random prime number from 0 to n(inputed from user) using the RandomGenerator class from the acm.utils package and for some reason it doesn't work! I've thought it through lots of times and I think this solution is right, bot it ends up giving numbers that are not wrong!
This is for a project at the uni and I have to use only acm.util! no scanners! only this kind of code
public int nextPrime(int n){
int num = rgen.nextInt(1, n);
boolean prime=false;
if (num==1){
return (num);
}else{
int i = 2;
int c = 0;
while ((i < num-1)&&(prime=false)){
if( (num % i) == 0){
c=c+1;
}
if((c==0)&&(i==(num-1))){
prime=true;
}
if(c>=1){
num = rgen.nextInt(1, n);
i=1;
}
i=i+1;
}
}
return (num);
}
= is for assignment and == is for comparison.
You need to change your condition
while ((i < num-1)&&(prime=false)){
to
while ((i < num-1)&&(prime==false)){ or
while ((i < num-1)&&(!prime)){
Here is a basic method to determine if a number is prime or not. This method is really only meant to understand the logic behind finding if a number is prime or not. Enjoy.
public boolean isPrime()
{
boolean prime = true;
for (int s = 2; s < original; s++)
if (original % s != 0 )
{
prime = true;
}
else
{
prime = false;
return prime;
}
return prime;
Your code is rather bizarre. Variable like c is not very clear, and the name doesnt help.
You could read other implementations.
I made some change to make it work. Traces help too !
public static int nextPrime(int n)
{
int num = (int)(1+Math.random()*n); // other generator
// TRACE HERE
System.out.println("START:"+num);
boolean prime=false;
// CHANGE HERE
if (num==2)
{
return (num);
}
else
{
int i = 2;
int c = 0;
// CHANGE HERE
while ((i < num-1)&&(prime==false))
{
// Not prime => next one
if( (num % i) == 0)
{
// TRACE HERE
System.out.println("YOU LOSE: :"+num+" divided by "+i);
c=c+1;
}
if((c==0)&&(i==(num-1)))
{
prime=true;
// TRACE HERE
System.out.println("BINGO:"+num);
// CHANGE HERE
break;
}
if(c>=1)
{
// SAME PLAYER LOOP AGAIN
num = (int)(1+Math.random()*n);
// TRACE HERE
System.out.println("RESTART:"+num);
i=1;
// CHANGE HERE
c=0;
}
i=i+1;
}
}
return (num);
}
Either you have misstated the problem or else you have not come close to coding the problem correctly. There are 4 prime numbers up to 10: {2,3,5,7}. If the user enters 10, should you give a random prime from this set, or a random one of the first 10 primes {2,3,5,7,11,13,17,19,23,29}? You said the problem was the first interpretation (where 11 would not be a valid response to 10) but you implemented an attempt at the second interpretation (where 11 would be a valid response to 10).
There is a simple way to generate a prime number uniformly within the primes in the range [1,1000000], say. Choose a random integer in the range and test whether it is prime. If so, return it. If not, repeat. This is called rejection sampling. It is quite complicated to get a uniformly random prime number without rejection sampling, since it's not easy to count or list the prime numbers in a large range. It is relatively easy to test whether a number is prime, and for n>1 it only takes about log n samples on average to find a prime in [1,n].

NthPrime- what's wrong with this while/for loop or set of if-statements?

Having trouble understanding what's wrong in the code.
I'm also trying to avoid using multiple methods if possible and just keep the functionality within the while loop.
public class NthPrime {
public static void main(String[] args) {
int n;
System.out.println("Which nth prime number do you want?");
n = IO.readInt();
if(n <= 0) {
IO.reportBadInput();
return;
}
if(n == 1) {
System.out.println("Nth prime number is: 2");
return;
}
int primeCounter = 1;
int currentNum = 3;
int primeVal = 0;
while(primeCounter < n) {
for(int x = 2; x < currentNum; x++) {
if(currentNum % x == 0) {
continue;
} else {
primeVal = currentNum;
primeCounter++;
}
}
currentNum++;
}
System.out.println(primeVal);
}
}
Your code assumes that every time it encounters a number coprime to the number it's checking, it has a prime. That is to say, your if block:
if(currentNum % x == 0) {
continue;
} else {
primeVal = currentNum;
primeCounter++;
}
says "If it's composite (i.e. divisble by x), then there's no point in continuing to test this number. However, if it's not composite, then we have a prime!" This is faulty because if there's a composite number above the coprime number, your code doesn't care.
This faulty test also gets run for every single coprime number below the number you're checking.
You may be able to fix this by moving the code that updates primeVal and increments primeCounter to the place where you're certain that currentNum is prime. This would be after the for loop is done checking all the numbers below currentNum.
General hint: Speed up your code by looping to the square root of currentNum, not currentNum itself. It's equivalent to what you have now, but faster.

Store prime numbers into partial array

I'm trying to store all the prime numbers 1-100 into a partial array, and then print the result.
I need to have them in separate methods.
I think I figured out how to tell if a number is prime, but not how to return that number back to the main method to be store into an array.
Here's my code so far:
Main method:
public static void main (String[] args) throws IOException {
int[] primeArray = new int[25];
primeArray[0] =2;
int numPrimes = 1;
boolean prime;
int currNumber;
for(currNumber=3; currNumber<=100; currNumber++) {
prime= isPrime(currNumber,primeArray,numPrimes);
if(prime=true) {
primeArray[numPrimes]=currNumber;
numPrimes++;
if (numPrimes==25)
break;
}
System.out.println(primeArray[numPrimes]);
}
}
isPrime method:
public static boolean isPrime (int currNum, int [] primeArray,int numPrimes) {
boolean prime=true;
for(int i=0; i<numPrimes; i++) {
if(currNumber/2%primeArray[i]==0)
prime=false;
break;
}
return prime;
} // end isPrime
Any advice would be appreciated; super confused right now.
You are doing a pretty good job, I can see a couple of errors right away:
if(prime=true) should be if(prime==true) or for booleans you normally use only the expression, i.e. if(prime)
Check the loop where you check for primehood. x % 1 will always be 0 ;)
A few things wrong with your code. In the main method, you are passing currNum in to the isPrime() method call. That variable doesn't exist, your code shouldn't compile. You want to pass currNumber into that method call. The second thing is your if statement is assigning the "prime" boolean to true, not checking it. It should just be if(prime).
In your isPrime() method, you can add a break; in the prime check because if it's divisible by a number, it's not prime, no need to check the rest of the divisors:
if(currNum%primeArray[i]==0) {
prime = false;
break;
}
Since you are iterating through the prime array, the for loop should stop at the number of primes, not the current number:
for(int i=0; i<numPrimes; i++)
I would change the isPrime signature as public static boolean isPrime(int number) and define it such that it would take a number and return true/false based on whether the number is prime or not.
public static boolean isPrime(int number) {
if(number < 2) {
return false;
} else if(number < 4) {
return true;
}
for(int i=2; i<=number/2; i++) {
if(number % i == 0) {
return false;
}
}
return true;
}

Categories

Resources