Finding a prime number using recursion in Java - java

I'm writing this problem for school and I have some issues with it. I can't get it to actually calculate the prime number. Obviously, when I run a test from main with the number 4 it says 4 is a prime number when we all know it's not. How do I need to write out the equation?
The instructions are as follows.
Use RECURSION to write this function (or make this function a wrapper over another recursive function)
* a number is prime if it is divisible only by itself and 1
* (that is, if it is not divisible by any number between * itself and 1;
* we can optimize and just check between 2 and the square root of the number).
* by convention, 1 is NOT prime
* this function returns true if its parameter is prime, false otherwise.
* One way to do this is to test all numbers between 2 and n; if any of them
* divides it, then it is not prime. If you reach the end, then it is.
* Examples:
* isPrime(1) => false
* isPrime(2) => true
* isPrime(3) => true
* isPrime(4) => false
*/
public static boolean isPrime(int n)
{
if (n == 0 || n == 1) {
return false;
} if (n == 2 || n == 3) {
return true;
} if (Math.sqrt(n) % 2 == 0) {
return true;
}else
return isPrime(n);
}
The below code is from the grader.java that my prof uses to grade the program. There are a few calls to the isprime method. It always seems to get hung up on 4 (I see why... 4 squared % 2 == 0) and 4 isn't a prime #.
public void testIsPrime()
{
Assert.assertEquals("1 is not prime", false,Assignment4.isPrime(1));
Assert.assertEquals("2 is prime", true,Assignment4.isPrime(3));
Assert.assertEquals("4 is not prime", false,Assignment4.isPrime(4));
Assert.assertEquals("7 is prime", true,Assignment4.isPrime(7));
Assert.assertEquals("9 is not prime", false,Assignment4.isPrime(9));
Assert.assertEquals("35 is not prime", false,Assignment4.isPrime(35));
Assert.assertEquals("37 is prime", true,Assignment4.isPrime(37));
}

The assignment is giving you a vital hint:
or make this function a wrapper over another recursive function
public static boolean isPrime_helper(int number, int divisor)
{
/* write code to return true if divisor is > square root of number */
/* which can also be expressed divisor squared is > number */
/* write code here to test if divisor divides number without remainder */
/* and return false if it does. Otherwise: */
return isPrime_helper(number, divisor + 2);
}
public static boolean isPrime(int number)
{
/* deal with the special cases 2, < 2, and even numbers here */
/* Otherwise: */
return isPrime_helper(number, 3);
}

cdlane's answer has the basic correction. I just want to make sure that you know where your try doesn't work. You have two fatal problems:
You have no simplification in your recursion. If you haven't hit the base cases (0-3), you recur with the same number, throwing you into an infinite loop.
Your sqrt clause is both needless and wrong. If the sqrt of a number is even, it cannot be prime. Is this supposed to be a test for stopping the recursion?

In Prime numbers, 2 can't be prime because you can divide it by 2 and it shouldn't be able to divide by 2. Hence, if number%2 is 0 or number is 2 you need to return false.
When a number is not 2 or it's not possible to divide it by 0, you can check for other numbers with a for loop inside your function.
Take a look at following code it helps you to understand what's going on:
public boolean isPrime (int number){
if ((number%2)==0 && number != 2) {
return false;
}
else {
for (int i =3; i*i<number; i++ )
{
if (number%i ==0)
return false;
}
return true;
}

Related

Having trouble understanding logic behind testing if numbers are prime or not

/**
* The isPrime method iterates through every number in the range of 1 - 100 and adds every prime number to a
list in the file created by the user
* #param filename The file that numbers will be added to
*/
public static void isPrime(String filename) throws IOException
{
boolean status = true; // tells method if number is prime or not (if status = true, number is prime)
// opens up previously-created file for writing
FileWriter fwriter = new FileWriter(filename, true);
PrintWriter outputFile = new PrintWriter(fwriter);
for (int i = 1; i <= 100; i++)
{
// check if each number is prime
status = checkPrime(i);
if (status == true && i != 1)
{
outputFile.println(i);
}
}
outputFile.close();
}
/**
* The checkPrime method tests each number passed in as a parameter to see if it is prime
* #param num Integer to be tested
* #return Returns a boolean value of either true or false
*/
public static boolean checkPrime(int num)
{
int remainder; // used to test whether number is prime or not
for (int j = 2; j < num; j++)
{
remainder = num % j;
if (remainder == 0)
{
return false;
}
}
return true;
}
So this is a segment from my assignment. The code runs, but what I need help with is understanding the logic of why the 2nd method, checkPrime() works. I realize it's probably obvious, but I'm a new cs student, so if anyone is willing to explain why this works to me I'd appreciate it.
The % operator is the remainder operator. It is interating from 2 to num to see if the prime is divisible by any of those numbers. As soon as it is, it can't be a prime so it returns false. If finished and no divisor, it returns true.
But there is a more efficient way. Only divide the candidate number num by values staring with 2 up to the square root of num. Think about it, if there is no remainder up to that point, then no other number from the square root of num to num will divide it.
So first check for divisibility by 2. Then starting with 3 by just the odd numbers.
So the method would look like this.
public static boolean checkPrime(int num)
{
int remainder; // used to test whether number is prime or not
if(num % 2 == 0) {
return false;
}
for (int j = 3; j < (int)Math.sqrt(num)+1; j+=2)
{
remainder = num % j;
if (remainder == 0)
{
return false;
}
}
return true;
}
By definition, a prime number is a number that is only divisible by 1 or itself. For a number to be divisible the remainder of division should be 0.
Examples
5 is prime as it's only divisible by itself and 1:
5/5=1 remainder 0
5/4=1 remainder 1
5/3=1 remainder 2
5/2=2 remainder 1
5/1=5 remainder 0
While 4 is not prime because it's also divisible by 2:
4/4=1 remainder 0
4/3=2 remainder 1
4/2=2 remainder 0
4/1=4 remainder 0
The operator % is used to calculate the remainder 5%2=1.
Using this operator we can loop through all the numbers between 2 and num, for (int j = 2; j < num; j++) (we don't want to check 1 and num itself) and check the remainder, if (remainder == 0). Once remainder is equal to 0, the loop is broken and false is returned meaning the number is not prime. Otherwise, the loop finishes and the method returns true signalling that the number is prime.

Can someone help me to understand this for loop?

Hello i'm new learner at java, the tutor on Udemy gave us this method but he didn't explain it, i found it hard to understand, and i tried to execute it, but still the same thing.
PS : sorry for my English i'm Arabian.
This is the method:
public static boolean isPrime(int n) {
if(n == 1) {
return false;
}
for(int i = 2; i <= n/2; i++) {
if(n % i == 0) {
return false;
}
}
return true;
}
The code loops through all numbers from 2 to n/2 and checks if n is divisible by that number. If it is divisible by any of these numbers the function returns false as n has a divisor. If we have found no divisor from 2 to n/2 the number is prime. A better approach would be to loop to the square root of n.
The method isPrime(int n) takes an integer n and checks whether it is prime or not.
First it checks whether n is equal to 1. If it is the method returns false, because 1 is not prime.
Afterwards it loops through all the numbers between 2 and n/2, and checks if n is divisible by that number. If it is, the method returns false because then it is not prime.
The reason why it does not check every number from 2 til n is because it would be redundant. The number n can never be expressed as a product of a whole number and a number that is bigger than n/2, except n but then it would not be a prime number.

Check if number of digits of an integer is even with recursion

Need to check if number of digits of an integer is even with recursion.
Here is without recursion:
private static boolean jeParanBrCifara(int n) {
int brojCifara = String.valueOf(n).length();
if (brojCifara % 2 == 0)
return true;
else
return false;
}
and here is code for counting numbers with the recursion
public int DigitsCount(int Number) {
if (Number > 0) {
Count = Count + 1;
DigitsCount(Number / 10);
}
return Count;
}
But how to make an recursive method that will take an integer as parameter and return true (if number of digits is even) of false ?
I did this, but not sure if it is correct:
static int Count = 0;
public static boolean isEven(int Number) {
boolean even = false;
if (Number > 0) {
Count = Count + 1;
isEven(Number / 10);
}
if (Count % 2 == 0) {
even = true;
}
return even;
}
Any tips/hints?
Consider how the answer changes as you increase the number of digits:
1 digit - false
2 digits - true
3 digit - false
4 digits - true
and so on
See the pattern? The answer to a problem with one digit is false, and the answer to a problem with n+1 digits is the inverse of the answer for the problem with n digits.
Since you already know that reducing the number of digits by one is done by dividing by 10 in integers, you should be able to write a solution to the above algorithm with just a few lines of code.
Recursion is to express the function in terms of itself, but for a smaller problem. Something like this:
If the number is 9 or lower, it's false.
If the number is 99 or lower, it's true.
Otherwise, divide by 100 and check if the result has an even number of digits...
Since we know that Number%2 will return 0 or 1, i'm going to assume that you shouldn't be using that to determinate if the number is even or odd.
You should set your base case (If 1 then return false)
Then check if the n-1 was even or odd and return the opposite.
Let's assume we're only dealing with positive numbers, something like this could be written:
public static boolean IsEven(int n)
{
return n >= 10
? !IsEven(n / 10)
: false;
}
On the same line as mentioned by dasblinkenlight above
public static boolean isEven(int num){
if(num>=10){
return !isEven(num/10);
}
return false;
}

Java: Incorrect Output when Factoring

I'm trying to write a function to determine whether a number is "ugly". For a number to be "ugly", it must have no prime factors other than 2, 3, or 5.
Here's my attempt:
public class Solution {
public boolean isPrime(int num) {
if (num == 2) {
return true;
}
if (num % 2 == 0) {
return false;
}
if (num < 0) {
num *= -1;
}
for (int i = 3; i <= Math.sqrt(num); i += 2) {
if (num % i == 0) {
return false;
}
}
return true;
}
public boolean isUgly(int num) {
if (num < 0) {
num *= -1;
}
for (int i = 7; i <= Math.sqrt(num); i += 2) {
if ((num % i == 0) && isPrime(num)) {
return false;
}
}
return true;
}
}
I'm getting true for input = -2147483648 when it should be false. Is it possible there's an overflow here? I've gone over my code and the logic looks right to me...
Thanks!
The problem is Integer.MIN_VALUE*-1 = Integer.MIN_VALUE leading to Math.sqrt(Integer.MIN_VALUE) which returns NaN on a negative number, so then when you perform this operation 7 <= Math.sqrt(Integer.MIN_VALUE) it returns false and doesn't even enter the for loop resulting in the program returning true.
I hope this explanation helps.
Yeah, I guess so.
Java lower limit for int is -2147483648 and upper 2147483647. As shown in
public class MainClass {
public static void main(String[] arg) {
System.out.println(Integer.MAX_VALUE);
System.out.println(Integer.MIN_VALUE);
}
}
Negative numbers are tricky in such a question.
You have to take the absolute number and factor it. In your original source, you didn't do this. It meant that you got a NaN from the Math.sqrt method. Which also meant that you got false when you compared it to 7.
So your original method would have returned true for all negative numbers.
But changing the sign (which, by the way can be done by num = -num rather than multiplication), which would solve it for all negative numbers, actually introduced an overflow into the program.
The number -2147483648 is, in fact, -231. The maximum positive number allowed in an int is 231-1. So the number - Integer.MIN_VALUE always overflows... into itself. It remains negative after you negate it!
So you run into that NaN again.
But note - since the number is -231, it doesn't, in fact, have any other prime factors other than 2. So the method really should return true for it - assuming that you are not considering -1 a prime.
So I believe that your expectation that it should be false is incorrect - but it depends on the assignment's definition of the prime factors of negative numbers.
Notes:
Your program checks isPrime(num) instead of isPrime(i), and therefore it will always return true. num cannot both be divisible by i and be prime at the same time.
Limiting your program to the square root of num is wrong to begin with. For example, take the number 881305274. Its prime factors are 2 and 440652637. But 440652637 is much bigger than sqrt(881305274). The square root trick works for prime testing, because any factor that is bigger than the root has to be multiplied by a factor that's smaller than the root. But this doesn't apply to the "ugly" problem.
Also, prime numbers are not considered "ugly" as they are a factor of themselves. But your program, because it limits itself to the square root, will never return false for prime numbers.

Check whether number is even or odd

How would I determine whether a given number is even or odd? I've been wanting to figure this out for a long time now and haven't gotten anywhere.
You can use the modulus operator, but that can be slow. If it's an integer, you can do:
if ( (x & 1) == 0 ) { even... } else { odd... }
This is because the low bit will always be set on an odd number.
if ((x % 2) == 0) {
// even
} else {
// odd
}
If the remainder when you divide by 2 is 0, it's even. % is the operator to get a remainder.
The remainder operator, %, will give you the remainder after dividing by a number.
So n % 2 == 0 will be true if n is even and false if n is odd.
Every even number is divisible by two, regardless of if it's a decimal (but the decimal, if present, must also be even). So you can use the % (modulo) operator, which divides the number on the left by the number on the right and returns the remainder...
boolean isEven(double num) { return ((num % 2) == 0); }
I would recommend
Java Puzzlers: Traps, Pitfalls, and Corner Cases Book by Joshua Bloch
and Neal Gafter
There is a briefly explanation how to check if number is odd.
First try is something similar what #AseemYadav tried:
public static boolean isOdd(int i) {
return i % 2 == 1;
}
but as was mentioned in book:
when the remainder operation returns a nonzero result, it has the same
sign as its left operand
so generally when we have negative odd number then instead of 1 we'll get -1 as result of i%2. So we can use #Camilo solution or just do:
public static boolean isOdd(int i) {
return i % 2 != 0;
}
but generally the fastest solution is using AND operator like #lucasmo write above:
public static boolean isOdd(int i) {
return (i & 1) != 0;
}
#Edit
It also worth to point Math.floorMod(int x, int y); which deals good with negative the dividend but also can return -1 if the divisor is negative
Least significant bit (rightmost) can be used to check if the number is even or odd.
For all Odd numbers, rightmost bit is always 1 in binary representation.
public static boolean checkOdd(long number){
return ((number & 0x1) == 1);
}
Works for positive or negative numbers
int start = -3;
int end = 6;
for (int val = start; val < end; val++)
{
// Condition to Check Even, Not condition (!) will give Odd number
if (val % 2 == 0)
{
System.out.println("Even" + val);
}
else
{
System.out.println("Odd" + val);
}
}
If the modulus of the given number is equal to zero, the number is even else odd number. Below is the method that does that:
public void evenOrOddNumber(int number) {
if (number % 2 == 0) {
System.out.println("Number is Even");
} else {
System.out.println("Number is odd");
}
}
This following program can handle large numbers ( number of digits greater than 20 )
package com.isEven.java;
import java.util.Scanner;
public class isEvenValuate{
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
String digit = in.next();
int y = Character.getNumericValue(digit.charAt(digit.length()-1));
boolean isEven = (y&1)==0;
if(isEven)
System.out.println("Even");
else
System.out.println("Odd");
}
}
Here is the output ::
122873215981652362153862153872138721637272
Even
/**
* Check if a number is even or not using modulus operator.
*
* #param number the number to be checked.
* #return {#code true} if the given number is even, otherwise {#code false}.
*/
public static boolean isEven(int number) {
return number % 2 == 0;
}
/**
* Check if a number is even or not using & operator.
*
* #param number the number to be checked.
* #return {#code true} if the given number is even, otherwise {#code false}.
*/
public static boolean isEvenFaster(int number) {
return (number & 1) == 0;
}
source
You can use the modulus operator, but that can be slow. A more efficient way would be to check the lowest bit because that determines whether a number is even or odd. The code would look something like this:
public static void main(String[] args) {
System.out.println("Enter a number to check if it is even or odd");
System.out.println("Your number is " + (((new Scanner(System.in).nextInt() & 1) == 0) ? "even" : "odd"));
}
You can do like this:
boolean is_odd(int n) {
return n % 2 == 1 || n % 2 == -1;
}
This is because Java has in its modulo operation the sign of the dividend, the left side: n.
So for negatives and positives dividends, the modulo has the sign of them.
Of course, the bitwise operation is faster and optimized, simply document the line of code with two or three short words, which does it for readability.
Another easy way to do it without using if/else condition (works for both positive and negative numbers):
int n = 8;
List<String> messages = Arrays.asList("even", "odd");
System.out.println(messages.get(Math.abs(n%2)));
For an Odd no., the expression will return '1' as remainder, giving
messages.get(1) = 'odd' and hence printing 'odd'
else, 'even' is printed when the expression comes up with result '0'
package isevenodd;
import java.util.Scanner;
public class IsEvenOdd {
public static void main(String[] args) {
Scanner scan = new Scanner(System.in);
System.out.println("Enter number: ");
int y = scan.nextInt();
boolean isEven = (y % 2 == 0) ? true : false;
String x = (isEven) ? "even" : "odd";
System.out.println("Your number is " + x);
}
}
Here is full example:-
import java.text.ParseException;
public class TestOddEvenExample {
public static void main(String args[]) throws ParseException {
int x = 24;
oddEvenChecker(x);
int xx = 3;
oddEvenChecker(xx);
}
static void oddEvenChecker(int x) {
if (x % 2 == 0)
System.out.println("You entered an even number." + x);
else
System.out.println("You entered an odd number." + x);
}
}

Categories

Resources