Why this program for finding prime numbers outputs both answers? - java

This Code works properly for numbers upto 4 but then prints wrong or sometimes both, "Number is Prime" and "not Prime".
package timepass;
import java.util.Scanner;
public class Timepass {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
System.out.print("Enter the no :");
int n = sc.nextInt();
if (n==1 || n==0) {
System.out.println("It is not a prime no");
}
else if (n > 1) {
for(int i = 2; i<n; i++) {
if (n % i ==0) {
System.out.println("It is not a prime number");
break;
} else {
System.out.println("It is a prime number");
}
}
}
}
}

There is slight mistake in the logic.
You have to check all the integers from 2 to n-1, if they are factors of n and then make the final verdict.
Have a look at the following implementation:
import java.util.Scanner;
public class Timepass {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
System.out.print("Enter the no :");
int n = sc.nextInt();
if (n==1 || n==0) {
System.out.println("It is not a prime no");
}
else if (n > 1) {
boolean isPrime = true;
for(int i = 2; i<n; i++) {
if (n % i ==0) {
isPrime = false;
break;
}
}
if(isPrime) {
System.out.println("It is a prime number");
}else{
System.out.println("It is not a prime number");
}
}
}
}
PS: Also search for more efficient logics to check if the number is prime. For example: In the above code, their is no need to iterate from 2 until n-1. You can stop at n/2.

I see the problem.
Hint: a number is prime if there are no factors. Your code is printing "prime" when >>a<< number is not a factor.

Look at the example 5 and your loop.
2: not a factor, print "It is a prime number"
3: not a factor, print "It is a prime number"
4: not a factor, print "It is a prime number"
When can you as a human tell that it is a prime number? Surely not already at 2.
(Actually you can at 3, but your loop condition is inefficient....)
So why do you print already? You should not.
Look at 9:
2: not a factor, print "It is a prime number"
3: is a factor, print "It is not a prime number"; break, stop looping
Again, at 2 you do not know yet but print anyway; at three you know and stop.
The solution is to print in all cases only when leaving the loop. You do so correctly before the break for "not prime". But you print several times for "prime", possibly wrongly and possibly later again for "not prime".
The point to print "prime" is after going through all of the loop without finding a factor.
Make sure that you do not do that printing after leaving the loop with break for "not prime". You can do so by introducing a function which does the prime check and returns a value indicating the result. That function can return where you currently break and after the loop. Then print the result text from the calling code, based on the return value.

You should be using a flag variable in order to check the number whether it is prime or not. The problem with your case is that everytime it check if the number is divisible by i and if this condition becomes false then it goes to the else condition and prints 'not prime' and this is wrong the program should wait for the loop to end and then it should print any result.
So use a flag variable, initialize it false and if the number is divisible by any value of i then make the value of flag true and break out of loop.
After the loop check for flag variable and if the variable is true print not prime else prime .

//you can use flag instead of printing the massage inside the for loop
// if flag is true means the number is not a prime number
boolean flag = false;
for(int i =2; i< n; i++){
if(n % i ==0){
flag = true;
break;
}
}
if (flag) {
System.out.println("It is not a prime number");
} else {
System.out.println("It is a prime number");
}

import java.util.Scanner;
class Timepass {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
System.out.print("Enter the no :");
int n = sc.nextInt();
if (n==1 || n==0) {
System.out.println("It is not a prime no");
}
else if (n > 1) {
for(int i = 2; i<n; i++) {
if (n % i ==0) {
System.out.println("It is not a prime number");
break;
} else {
System.out.println("It is a prime number");
break;
}
}
}
}
}

Related

While loop is not looping back to the start with a new input from the user

I have been trying to perfect this program on my own, and I just can't see what I'm doing wrong. The aim of this program is to do these things.
1) ask user for number
2) if the number is positive, print out the number
3) if the number is also a prime number, print that it's also a prime number
4) keep doing the above things until a negative number is inputed by the user.
The problem is, the program only works and determines if a number entered is a prime number or not, at the beginning. After that, when the user is asked for another number (if it's greater than 0), the program just doesn't loop back to the beginning to determine if the number is prime. Instead, it just sticks to what the value at the beginning was determined to be (prime or not prime) and prints out the same statement as what you would get for the first value, for the second. I want it to reevaluate the value every time to see if the number is prime or not, until the user inputs a negative number.
P.S. This is my first year going for a C.S degree. I find programing really fun and challenging (the concept). But I embrace it that challenge and find a sense of accomplishment every time I work through these problems.
import java.util.Scanner;
public class Prime3 {
public static void main(String[] args) {
int userNum;
int i = 2;
boolean isPrime = true;
Scanner input = new Scanner(System.in);
// Ask user for initial number
System.out.println("Please enter a number.");
userNum = input.nextInt();
// Determining whether or not number entered is prime
while (i <= userNum/2) {
System.out.println("Checking if " + i + " is a multiple of n");
if (userNum%i == 0) {
System.out.println(i + " is a multiple of " + userNum);
isPrime = false;
break;
}
i++;
}
// Print out user number if the number is positive.
while (userNum > 0) {
System.out.println("You entered the number, " + userNum);
if (isPrime) { // If it's a prime, state that it's a prime
System.out.println("No even multiples found. " + userNum + " is a prime number");
}
userNum = input.nextInt();
}
System.out.println("Invalid input. Program now ending.");
System.exit(0);
}
}
Well, I see the problem. You should move while (userNum > 0) to the top. So your final code should look something like this:
public class Prime3 {
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
// Ask user for initial number
System.out.println("Please enter a number.");
int userNum = input.nextInt();
while (userNum > 0) {
int i = 2;
boolean isPrime = true;
// Determining whether or not number entered is prime
while (i <= userNum / 2) {
System.out.println("Checking if " + i + " is a multiple of n");
if (userNum % i == 0) {
System.out.println(i + " is a multiple of " + userNum);
isPrime = false;
break;
}
i++;
}
// Print out user number if the number is positive.
System.out.println("You entered the number, " + userNum);
if (isPrime) { // If it's a prime, state that it's a prime
System.out.println("No even multiples found. " + userNum + " is a prime number");
}
userNum = input.nextInt();
}
System.out.println("Invalid input. Program now ending.");
System.exit(0);
}
In general construction of this code is error prone. You should do something like:
set userNum = 0
enter while (userNum >=0)
Call method which check if userNum is positive, if yes print
Call method which check if userNum is prime, if yes print
get new value from input console into userNum
end body of loop.
If you follow there should be no problem.

Java - Increasing performance of a simple prime number validator

I'm in an intro to Java class and just finished an assignment, but I was left with a question in my head. I did not have time to ask my professor yet and it's a bit off topic from what we're doing anyhow.
Basically we had a program that will validate if a user inputted integer is prime or not. If it isn't prime, it calculates the closest prime number smaller than the input. For example:
Enter an integer: 4
4 is not a prime number. The closest prime number is 3.
The program works as intended using a loop if the input is not prime. Here is my code:
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
int number;
System.out.print("Please enter a positive, non-zero integer: ");
number = input.nextInt();
input.close();
if (isValid(number) == true) {
if(isPrime(number) == true) {
System.out.printf("%d is a prime number.", number);
} else {
switch(number) {
case 1:
System.out.print("1 is not a prime number. \n");
System.out.print("We cannot find the nearest prime.");
break;
default:
System.out.printf("%d is not a prime number.", number);
System.out.printf("\nThe nearest prime number is %d.", getNearestPrime(number));
}
}
} else {
System.out.print("Invalid input. Please run again.");
System.exit(1);
}
}
public static boolean isValid(int number) {
if (number > 0) {
return true;
} else {
return false;
}
}
public static boolean isPrime(int number) {
int i;
if(number == 1) {
return false;
} else {
for(i = 2; i < number; i++) {
if(number%i == 0) {
return false;
}
}
return true;
}
}
public static int getNearestPrime(int number) {
do {
number--;
} while (isPrime(number) == false);
return number;
}
It's important to note we were required to create the three methods listed below main.
My question is this: is there a way to increase performance when calculating larger ints in this scenario?
If I was to input 2,147,483,647, the program takes about 10 seconds to recognize it's prime. If I enter 2,147,483,646, it takes roughly the same time to find the closest prime.
I completely understand why this happens, but it seems like any high level Java applications I've used can computer way more complex things much faster than my simple program can.
I'm genuinely just curious how experienced programmers handle something like this. Thank you!
Several simple things you can change:
1) A prime number will never be even, so once you check if a number is divisible by two, you don't need to check if it is divisible by any other even number. So you can simplify your loop a little. (Just add an if statement to check if the number is 2 and then start i at three)
2) You only have to loop until the square root of the number.
int i;
if(number == 1) {
return false;
}
if(number == 2) {
return true; //2 is a prime number
}
if (number % 2 == 0) {
return false;
}
for(i = 3; i* i <= number; i+=2) {
if(number%i == 0) {
return false;
}
}
return true;
Well one thing to note is that algorithmic wise there are more efficient algorithms to use. See this answer for details
Regarding implementation you can for example employ some tricks such as caching of recent results if you want to increase performance.
A more efficient approach but perhaps outside the scope of a course would be to use a list of precalculated primes.
You can find one in the internet or you can run a program once to precalculate them up to a given point.
Do note that this approach would trade off some memory for the sake of speed.

Console input in Java

This is simple code but I am not able to figure out why it is accepting two lines of input:
import java.io.*;
import java.util.*;
public class Solution {
public static void main(String[] args) {
Scanner scan = new Scanner (System.in);
String inputString = scan.nextLine();
int n = Integer.parseInt (inputString);
for (int i = 1; i <= n; ++i) {
inputString = scan.nextLine();
int num = Integer.parseInt (inputString);
System.out.println ("Checking prime of: " + num);
for (int j = 2; j*j < num; ++j) {
if (num % j == 0) {
System.out.println ("Not prime");
break;
}
}
System.out.println ("Prime");
}
}
}
Now when I run with the following input:
3
12
5
7
The program prints the following:
Checking prime of: 12
Not prime
Prime
Checking prime of: 5
Prime
Checking prime of: 7
Prime
Note the second Prime above when it has not consumed any input.
I must be making a simple mistake but not able to figure out what is wrong. If someone could point out what I am doing wrong that would be much appreciated.
This line is being printed always, every cycle.
System.out.println ("Prime");
Add a flag variable instead, inside your for 1st loop
boolean isPrime = true;
And inside your if:
if (num % j == 0) {
isPrime = false;
break;
}
Then have another condition
if (isPrime) {
System.out.println ("Prime");
} else {
System.out.println ("Not prime");
}
That's it
for (int j = 2; j*j < num; ++j) {
if (num % j == 0) {
System.out.println ("Not prime");
break;
}
}
System.out.println ("Prime");
The last line is called either way. You need to either initialize a flag to help you figure out if the loop ended early, or simply return whenever you print "Not prime".
You do a scan on the 2nd line of the main method, then again at the top of your loop. The first one consumes the first line of input, but all you do with it is parse it into an int, you don't check it and don't output anything for it.
import java.io.*;
import java.util.*;
class Solution {
public static void main(String[] args) {
Scanner scan = new Scanner (System.in);
String inputString = scan.nextLine();
int n = Integer.parseInt (inputString);
a: for (int i = 1; i <= n; ++i) {
inputString = scan.nextLine();
int num = Integer.parseInt (inputString);
System.out.println ("Checking prime of: " + num);
for (int j = 2; j*j <= num; ++j) {
if (num % j == 0) {
System.out.println ("Not prime");
continue a;
}
}
System.out.println ("Prime");
}
}
}
here you have pay attention over two points.
1. about break statement
that is it will break u from innermost loop only and that is the reason "prime" is printed whether the number is prime or not . so use labelled loop concept as i have used with "continue" .
your logic in "for loop" of checking the number whether it is prime or not is little bit wrong correct it as i have corrected that for(int j=2;j*j<=num;++j)
that is "<=" should be used in place of "<" otherwise on input 9,25etc.it will show prime which is wrong

Switch case syntax in Java

can't seem to find the syntax mistake in this switch statement. Any help is much appreciated.
Source code:
import java.util.Scanner;
public class SwitchCasing {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
String input = sc.nextLine();
try {
int number = Integer.parseInt(input);
switch(number) {
case 1:
if(number < 0) {
System.out.println("Number is smaller than 0.");
break;
}
case 2:
if(number > 0){
System.out.println("Number is greater than 0.");
break;
}
default:
System.out.println("Number is 0.");
}
} catch(IllegalArgumentException e) {
System.out.println("Please insert a valid number.");
}
sc.close();
}
}
The output is always "Number is 0", no matter what value is entered.
Thanks!
Those case labels aren't for you labeling purposes; they are for Java to compare number so it can execute the case.
It will start execution at the block for case 1: if number is 1. Because 1 isn't less than 0, that block won't produce any output.
It will start execution at the block for case 2: if number is 2. Because 1 isn't less than 0, that block will produce the output "Number is greater than 0.".
Any other number will go to the default case and produce the output "Number is 0.", even though your output is incorrect.
You can't test cases that way with a switch statement. Change it to the equivalent if/else construct.
if(number < 0){
System.out.println("Number is smaller than 0.");
}
else if(number > 0){
System.out.println("Number is greater than 0.");
}
else {
System.out.println("Number is 0.");
}
case 1: means that number equals 1. But since 1 is not less than 0 you'll never see "Number is smaller than 0.", and you won't break. (The break is inside the if (number < 0) part).
case 2: means that number equals 2. You'll enter this case if you enter a 2.
That leaves default for all other values you might enter, which I'm guessing are most of them.
You really don't want a switch in this situation. You should be using an if-else construct, like this:
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
String input = sc.nextLine();
try{
int number = Integer.parseInt(input);
if(number < 0) {
System.out.println("Number is smaller than 0.");
} else if(number > 0) {
System.out.println("Number is greater than 0.");
} else {
System.out.println("Number is 0.");
}
} catch(IllegalArgumentException e) {
System.out.println("Please insert a valid number.");
} finally {
sc.close();
}
}
As first, do you know you can do int number = sc.nextInt(); you do not need to parse the input and it assures that the user gives you a int.
As for your switch case your break; are inside if statements so when the code reads break it breaks our of the loop containing it. In your case it breaks out of the if/else statement not the switch case.
Hope I could help!

prime numbers switch in a java program has unexpected output

I'm trying to create a program that reads a list of 10 integers and asks the user whether they'd like to know if the integers entered are even/odd, prime, or their sign.
I don't see where the mistake is:
import java.io.*;
public class Menu1 {
public static void main(String args[])throws IOException{
BufferedReader b=new BufferedReader(new InputStreamReader(System.in));
int array[]=new int[10];
int a=0, i=0;
System.out.println("Welcome, please enter 10 integers:");
try{
for(i=0;i<10;i++){
System.out.println("Enter integer "+(i+1)+":");
array[i]=Integer.parseInt(b.readLine());
}
}catch(NumberFormatException e){
System.err.println("Not an integer! "+e.getMessage());
}
System.out.println("What would you like to know?\n(1) Even/Odd\n(2) Primes\n(3) Sign");
try{
a=Integer.parseInt(b.readLine());
}catch(NumberFormatException e){
System.err.println("Not an integer! "+e.getMessage());
}
switch (a){
case 1:
for(i=0;i<10;i++){
if(array[i]%2==0)
System.out.println(array[i]+" is even");
else
System.out.println(array[i]+" is odd");
}
break;
case 2:
for(int j=0;j<10;j++){
for(i=2;i<array[j];i++){
if(array[j]%i==0)
System.out.println(array[j]+" isn't prime");
else
System.out.println(array[j]+" is prime");
}
}
break;
case 3:
for(i=0;i<10;i++){
if(array[i]>0)
System.out.println(array[i]+" is positive");
else if(array[i]<0)
System.out.println(array[i]+" is negative");
else
System.out.println(array[i]+" has no sign");
}
break;
default:
System.out.println("Invalid Option");
}
}
}
case 1 and case 3 work just fine, case 2 is where the strange output occurs; any help will be greatly appreciated
In your code for case 2:
case 2:
for(int j=0;j<10;j++){
for(i=2;i<array[j];i++){
if(array[j]%i==0)
System.out.println(array[j]+" isn't prime");
else
System.out.println(array[j]+" is prime");
}
}
break;
you have put a System.out.println() statement that will execute for every iteration of the for loop. So, if a given element in your array, array, is 5, your code will print out whether or not your number is divisible by every number from 2 to 5. This probably isn't what you want.
To fix this, there are a few options: for one, you could have a boolean flag that you set when you discover that the number isn't prime, and then check that and print your results after the inner for loop:
case 2:
for(int j=0;j<10;j++){
boolean isPrime = true; // assume it's prime
for(i=2;i<array[j];i++){
if(array[j]%i==0)
isPrime = false;
break; // get out of the inner for loop early
}
if(isPrime)
System.out.println(array[j]+" is prime");
else
System.out.println(array[j]+" isn't prime");
}
break;
This is a function to check if a number is prime or not:
public static boolean isPrimeNumber(int number) {
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;
}
You can call this function for every number you want to check.
Your case2 would be like:
case 2:
for(int j=0;j<10;j++){
if(!isPrimeNumber(array[j]))
System.out.println(array[j]+" isn't prime");
else
System.out.println(array[j]+" is prime");
}
break;
For a programming exercise, the answers given will do just fine. If this were a real application, using very large numbers, the algorithm that checks every possible divisor (or even the slight improvements on this) would be very slow.
Although it's possible to test for primality with certainty much more efficiently than this, in practice it's very, very efficient to check that a (very) large number is almost
certainly prime. This is what gets used in cryptographic applications.
For further details, you could look up Miller-Rabin.
If you want an implementation you can use off-the-shelf, then convert your number to a BigInteger and then use BigInteger.isProbablePrime(int certainty) to determine whether it's probably prime. You can make the "probably" very close to certainty and it'll still be extremely efficient.

Categories

Resources