prime numbers switch in a java program has unexpected output - java

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.

Related

Why this program for finding prime numbers outputs both answers?

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;
}
}
}
}
}

How to create a program that converts binary to decimal

I'm trying to convert binary to decimal, how do I change my code to be able to do that? Where did I mess up?
i tried looking at other examples, looking at java api and watching videos but i still can't figure out what mistake i have made.
package Calculator;
import java.util.Scanner;
public class Calculator {
public static void main(String[] args){
Scanner scan = new Scanner(System.in);
System.out.println("(2) Convert binary to decimal");
System.out.println("\n\n Please enter your choice: ");
int choice = scan.nextInt();
if(choice == 2){
scan.nextLine();
//prompt for user input
System.out.println("Please enter a binary number: ");
String binary = scan.nextLine();
char[] binaryArray = binary.toCharArray();
int i=1;
int integer=0;
//potential problem somewhere around here?
while(i<8){
if(binaryArray[i]==0) {
++i;
}else if(binaryArray[i]==1) {
switch(i) {
case 1:
integer+=128;
++i;
break;
case 2:
integer+=64;
++i;
break;
case 3:
integer+=32;
++i;
break;
case 4:
integer+=16;
++i;
break;
case 5:
integer+=8;
++i;
break;
case 6:
integer+=4;
++i;
break;
case 7:
integer+=2;
++i;
break;
case 8:
integer+=1;
++i;
break;
}
}
}
System.out.println("The decimal value of the binary number is: "+ integer);
scan.close();
}
}
}
The input is always 0. I've tried 11010110, 11111111,and 01010111. Always 0. I know the problem lies somewhere with my integer value not changing but I can't figure out what it specifically is.
This is happening because you are reading the input, and converting into an array of char.
Anywhere where you are making your comparisons to an int, you should instead be doing a comparison to a char, by wrapping your values in single quotations.
while(i<8){
if(binaryArray[i]=='0') {
++i;
}else if(binaryArray[i]=='1') {
switch(i) {
case 1:
integer+=128;
++i;
break;
case 2:
integer+=64;
++i;
break;
case 3:
integer+=32;
++i;
break;
case 4:
integer+=16;
++i;
break;
case 5:
integer+=8;
++i;
break;
case 6:
integer+=4;
++i;
break;
case 7:
integer+=2;
++i;
break;
case 8:
integer+=1;
++i;
break;
}
}
Others have already pointed out that you have got confused between 0 and 1, and '0' and'1'`.
Other problems:
Your i starts at 1, so you miss the most significant bit;
You will never actually hit case 8: in the switch because of the while (i < 8) loop guard.
This doesn't work unless you enter exactly 8 bits.
You can write the entire while loop in a much more concise way:
for (int i = 0; i < binaryArray.length; i++) {
integer *= 2; // shift the digits along by 1 place
if (binaryArray[i] == '1') {
integer += 1; // set the least significant bit.
}
}
You should get away from all those switch statements.
Say you have "10101101" as input.
set val = 0;
Then either multiply by val by 2 or shift left 1 bit. They're the same. It is important
you do this before adding the next bit.
Start from the left and if it's a '1', add a 1 to val. Otherwise, add 0.
Then repeat starting at multiply until you've gone thru the string.
val should then have the decimal version when you print it.

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.

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!

I have just started and i am trying to make an if else statement but i dont know how to connect else to if

I have started out recently, this site has helped me once and I'm hoping it helps me again.
I know I have to connect else to if but I don't know how, here is my code,
import java.util.Scanner;
public class even {
public static void main(String[] args) {
System.out.println("Enter a number.");
Scanner scan = new Scanner(System.in);
int n;
n = scan.nextInt();
boolean even;
even = n % 2 == 0;
if (even = true) {
System.out.println("Your number number is even");
else
System.out.println("Your number is odd");
}
}
}
and i am very sorry if this question is off topic but i am new and learning, please don't dislike it and suggest what to do next time
Close the brace, something like
if (even) { // even = true is not good. even == true would work. but if (even)
// is shorter.
System.out.println("Your number number is even");
} else {
System.out.println("Your number is odd");
}
When you say if (even = true) you are assigning true to even which also evaluates to true.
if (even == true) { //can be also written as if (even)
System.out.println("Your number number is even");
} else { //we enter the next block only when `even` is not true
System.out.println("Your number is odd");
}
More details about the if statement, here.
If/Else statements are knitted together by use of curly braces to control the flow of your code and logic. Your if-statement should be altered to:
if (even) {//even is true
System.out.println("Your number number is even");
} else {
System.out.println("Your number is odd");
}

Categories

Resources