Using Recursion to Convert Number to Other Number Bases - java

assume num >=0, base is between 2 and 10;
convert(13, 2) returns "1101"
Here is my code so far i get StackOverFlow error
public String convert(int num, int base) {
if (num < 0 || base < 2 && base >10) {
return"";
}
return convert(num / base, base) + (num % base);
}

Similar to what #saka1029 said about num < 0 needing to be num <= 0 and return ""; needing some attention when num=0, you have && base > 10 rather than || base > 10. You're essentially saying "if our number is negative (impossible given that the starting num is at least 0) or the base is less than two AND greater than 10 (also impossible, a number cannot be less than two and greater than 10), then return an empty String.
You're getting a StackOverflow error because your recursive function is an infinite loop. num cannot be less than 0 and base cannot be both less than two and greater than ten at the same time.

Related

Basic Java - Finding if a number is a prime number using while loop

I have a question regarding an answer that was given here a while ago.
I came up with the same answer myself in the code attached but I'm trying to understand why do I need to divide the input number by 2 (line 10), and not just let the loop run its course till the value of the input number achieved.
1 import java.util.Scanner;
2 public class numIsPrime {
3 public static void main(String[] args) {
4 Scanner sc = new Scanner(System.in);
5 int i = 2;
6 boolean isPrime = true;
7 System.out.println("Enter a number");
8 int num = sc.nextInt();
9
10 while (i < num ) // (i <= num / 2)
11 {
12 if (num % i == 0)
13 isPrime = false;
14 i++;
15 }
16
17 if (isPrime)
18 System.out.println(num + " is a prime number");
19 else // !isPrime
20 System.out.println(num + " isn't a prime number");
21
22 }
23 }
This is the simplest way to calculate if an integer n is probably a prime:
public static boolean isPrime (int n) {
if (n < 2) return false;
BigInteger bigInt = BigInteger.valueOf(n);
return bigInt.isProbablePrime(100);
}
You can insert this function call in a loop where you can pass a new number every iteration. I am using the implementation of BigInteger provided by Java to do the calculation, rather than writing my own. UNLESS this is a homework and you are required to write your own algorithm, I would use this solution.
This base method can then be used for calculating other types of prime numbers. A complete answer can be found here.
UPDATE:
The int parameter in BigInteger.isProbablePrime(int) is a measure of the uncertainty that the caller is willing to tolerate. The larger the number, the "slower" it executes (but the more certain it is). Also, going back to the original question (already answered in the OP's comments section):
why do I need to divide the input number by 2 (line 10), and not just
let the loop run its course till the value of the input number
achieved.
This is an optimization that will make your evaluation run twice as fast. For example, suppose an evaluation of n integers take 10 minutes to complete, excluding even numbers should take half the time. That's a significant improvement. Although you should not optimize prematurely, these sort of optimizations should be done right from the get go. Basically, we all know that even numbers are not prime, so why evaluate it? You want to evaluate unknowns. In my solution, I only evaluate values greater than 2 because by definition, values less or equal to 2 are not prime. I am merely solving that by definition or by mathematical properties.
As mentioned in the comments, dividing by 2 is a simplest optimization to reduce the number of checks, however, existing code has a few issues (e.g. returning true for 0 and 1 which are NOT prime numbers) and may be further optimized:
break/end the loop as soon as isPrime is set to false
skip even numbers by incrementing by 2
calculate until i * i <= num
If this limit is reached, it means that no factor i of num has been found in the range [2, num/i], therefore by definition of the prime numbers, all the remaining numbers in the range [num/i, num] are neither the factors of num, and therefore num is prime.
Scanner sc = new Scanner(System.in);
System.out.println("Enter a number");
int num = sc.nextInt();
boolean isPrime = num > 1 && (num % 2 != 0 || num == 2);
int i = 3;
while (isPrime && i * i <= num) {
if (num % i == 0)
isPrime = false;
i += 2; // skip even numbers
}
if (isPrime)
System.out.println(num + " is a prime number");
else
System.out.println(num + " isn't a prime number");
More optimizations are possible if the divisibles of 3 (except 3) are excluded similar to the exclusion of even numbers, then the search continues from 5 and the candidates for primality comply with 6n ± 1 rule (e.g., 5 = 6 - 1, 7 = 6 + 1, 11 = 12 - 1, 13 = 12 + 1, etc.):
boolean isPrime = num > 1 && (num % 2 != 0 || num == 2) && (num % 3 != 0 || num == 3);
int i = 5;
int d = 2;
while (isPrime && i * i <= num) {
if (num % i == 0)
isPrime = false;
i += d; // check only non-even numbers
d = 6 - d; // switch 2 to 4 and back to 2
}

Recursion - Finding the Amount of Even Digits in a Number

I'm having trouble with this problem. I am supposed to find the amount of even digits in a number.
So for example, if the number is 146, then there are 2 even digits.
And if the number is 802, then there are 3 even digits.
I was told that n % 10 is the value of the rightmost digit. n / 10 contains all of the digits except the rightmost digit.
public static int countEvenDigits(int n) {
int rightDigit = n % 10;
int count= 0;
if (rightDigit / 10 == 0) {
count++;
}
return countEvenDigits(count);
}
With recursion, you can do it like this
int calcRec(int num) {
if (num / 10 == 0) {
return num % 2 == 0 ? 1 : 0;
}else{
return (num % 10 % 2 == 0? 1:0)+calcRec(num/10);
}
}
But its not suitable case for using recursion.
Another answer:
public static int countEvenDigits(int number) {
if (number == 0) return 0;
int lastDigit = number % 10;
int firstDigits = number / 10;
if (lastDigit % 2 == 0) {
return 1 + countEvenDigits(firstDigits);
} else {
return 0 + countEvenDigits(firstDigits);
}
}
Recursion always needs one or more "base case"s, where recursion stops (in this case, no digits left); and one or more "recursive cases" where you continue to work with a smaller problem (with the firstDigits).
I agree with #kimreik that this is not a good use of recursion (as the problem could be better solved with a while-loop); but it is a very typical example when starting to learn to program recursion, as I suspect the OP is doing.
Ok so the idea of using recursion to process a series is that you define a function that process and removes one element from the set. Seeing as you are interested in digits you have 2 options to define your set from a given int.
The first option is to cast the int to a string and cast each character back into an int. Which is what I implemented below
Alternatively you could do division by your base (10) to the power of the significance of the digit (0 being the right most digit and counting left.) Or more eloquently as kimreik reducing the number by integer division sequentially. (142 / 10 / 10 == 142 / 100 == 1 == "142"[0])...
The syntax for converting your integer to a string is Integer.toString(int). This will be useful as it allows us to access each digit without doing any math and also allows us to take sub-strings which we can pass to the next instance of our recursive method.
Now that we have our array to process we need to address the fundamentals of recursion. Recursion has three parts. These parts are as follows, some starting state or initial values, a base case and a recursive step.
For this problem we must set our initial values for the count of even digits and we will be given a string to process. We will start our count at 0 but it will be a variable passed to each call to our method.
Our base case is the empty sting, that is a blank number. Which contains 0 even numbers. Because we are recurring towards an empty set this type of algorithm is called reductive.
Now our recursive step is where everything really happens. It must read a digit from our string and then remove it from the string by passing the remaining digits to the next instance of the function.
Now that we know what we need to do what does out function look like?
public class HelloWorld{
public static int recursiveGetEvenDigits(String arg){
int count = 0;
if(arg.length()<1){
return(0); // base case
}
else{
count = Character.getNumericValue(arg.charAt(0))%2 == 0 ? 1 : 0; //If else shorthand
return(count+recursiveGetEvenDigits(arg.substring(1)));
}
}
public static int getEvenDigits(int n){ // provide user arguments
return(recursiveGetEvenDigits(Integer.toString(n))); // set initial conditions
}
public static void main(String []args){
System.out.println(getEvenDigits(142));
}
}
Just to be funny the whole if else logic could be reduced to one line again with the same shorthand I used above.
public class HelloWorld{
public static int recursiveGetEvenDigits(String arg){
return arg.length() < 1 ? 0 : (Character.getNumericValue(arg.charAt(0)) % 2 == 0 ? 1 : 0)+recursiveGetEvenDigits(arg.substring(1));
}
public static int getEvenDigits(int n){ // provide user arguments
return(recursiveGetEvenDigits(Integer.toString(n))); // set initial conditions
}
public static void main(String []args){
System.out.println(getEvenDigits(142));
}
}
prints 2
here is a quick pseudo code
function sumEven(int num){
if(num==0)
return 0;
int var =num%10;
if(var % 2)
return var+(num/10)
else
return 0+(num/10)
}

Can someone explain me this recursive method?

This code counts the number 7 of your input. This is the code method:
public static int count7(int n) {
if (n == 0) {
return 0;
}
else if (n % 10 == 7) {
return 1 + count7 (n/10);
}
else {
return count7(n/10);
}
}
What does the else-if statement and else do? Thank you so much.
if (n == 0) {
return 0;
There are no 7s in 0, so return 0.
} else if (n % 10 == 7) {
checks if the least significant digit of the number is 7. If that's the case, the total number of 7s is 1 + the number of 7s in the number you get by removing that digit (by dividing the number by 10) :
return 1 + count7 (n/10);
} else {
If the least significant digit is not 7, the number of 7s is the number of 7s in n/10 :
return count7(n/10);
}
if (n % 10 == 7) if the remainder is 7 lets take example n=17 so 17%10 you are going to get 7 so add 1 means count that you have found 7 if you have not found then go to the else part and this time call by dividing it suppose this time n=28 clearly there is no 7 in this number so it will go to else if condition and it is going to be fail it will go to the else part and it will call the method by dividing n to 10 for the next iteration.
This is a recursive method.
The first if is the base case, i.e, if the numbers is 0, then it returns 0.
The else if checks if the digit is 7. If it is, then get the answer to the remaining digits (whether they have any 7s) using the same method, add 1 to it, and return the value.
The last else just removes one digit, and calls the method for the remaining digits.
This method counts the total amount of the digit 7 in a given number.
n % 10 == 7 inspects the least significant digit, and if it equals 7, then add 1 to the sum.
In any case, the algorithm goes on with the other digits by taking n / 10, which actually removes the least significant digit, and then calls the method recursively. As the number is decreasing with 1 digit with each call and the stop trigger n == 0 makes the method eventually stop, the final returned number counts the sevens in the initial number.
Example
count7(172) = 0 + count7(17) = 0 + 1 + count7(1) = 0 + 1 + 0 = 1
The function simply counts the total number of appearances of the digit 7 in any given non-negative integer.

Determine if a number is power of 4, logNum % logBase == 0 vs (logNum / logBase) % 1 == 0

Problem: check if a number is a power of 4.
my solution in java:
public static boolean isPowerOfFour(int num) {
return (Math.log(num) % Math.log(4) == 0);
}
But it seems off in some cases, for example when num is 64.
I found out that if I change the code a little bit, it works well.
public static boolean isPowerOfFour(int num) {
return (Math.log(num) / Math.log(4) %1 == 0);
}
I think both solutions do the same thing, check if the remaining of logNum/logBase is 0. But why the first solution doesn't work? Is it because the solution is incorrect or relative to some low level JVM stuff?
Thanks.
Building on #dasblinkenlight's answer, you can easily combine both conditions (first, a power of 2, then any power of 4 among all possible powers of 2) with a simple mask:
public static boolean isPowerOfFour(int num) {
return ((( num & ( num - 1 )) == 0 ) // check whether num is a power of 2
&& (( num & 0xaaaaaaaa ) == 0 )); // make sure it's an even power of 2
}
No loop, no conversion to float.
Checking if a number is a power of 4 is the same as checking that the number is an even power of 2.
You can check that a number x is a power of two by verifying that x & (x-1) is zero (here is the explanation of how this works)
If your number is not a power of 2, return false. Otherwise, shift the number right until you get to one, and count the number of shifts. If you shifted an odd number of times, return false; otherwise, return true:
public static boolean isPowerOfFour(int num) {
if ((num & (num-1)) != 0) {
return false;
}
int count = 0;
while (num != 1) {
num >>= 1;
count++;
}
return count % 2 == 0;
}
Demo.
Functions like Math.log return floating point numbers with a rounding error. So when num = 64 for example, Math.log (num) / Math.log (4) is not exactly 3, but a number close to 3.
public static boolean isPowerOfFour(int num) {
if (num > 0) {
while (num % 4 == 0) num /= 4;
}
return (num == 1);
}
This solution can be quite easily adapted to check whether num is a power of some other integer greater than 1.
The reason it doesn't work is because Math.log() returns a double. The answer of false is reflective of rounding errors; log(64) base e is an irrational number but Java needs to truncate it to fit it's width.

Can anyone explain this code for me?

public int sumOfDigits(int num){
return num == 0 ? 0 : num % 10 + sumOfDigits(num/10);
}
This is a recursive calculation of the sum of digits - as long as you haven't consumed all the digits, it adds the last one with the sum of all the previous ones.
sumOfDigits is a method which accepts int argument and the return type is also int.
If 0 is passed then it will return 0 other wise it will return num % 10 + sumOfDigits(num/10)
If a number other than 0 is passed this will continue as long as entered number becomes 0
return num == 0 ? 0 : num % 10 + sumOfDigits(num/10);
Is equivalent to:
if(num==0)
{
return 0;
}
else
{
return num % 10 + sumOfDigits(num/10); // this is recursive call. It gets called until num is reduce to 0
}
This basically calulates as following:
If num=768 result= 7+6+8.
That is the Java ternary operator. It is similar to ternary operators in other languages. In this case:
return <boolean expression> ? <if true> : <if false>;
You have posted a recursive algorithm to calculate the sum of digits in an integer.
Two equivalent methods are posted below:
public int sumOfDigitsIf(int num) {
if (num == 0) {
return 0;
} else {
return num % 10 + sumOfDigitsIf(num / 10);
}
}
public int sumOfDigitsLoop(int num) { // useful to examine if you aren't used to recursive algorithms
int value = 0;
while (num > 0) {
value += num % 10;
num /= 10;
}
return value;
}
This function calculates the sum of the digits of the number recursively. First, if the number is 0, it returns 0, as the sum of the digits of 0 is 0. Then, it calculates the digit in the 1s place with num % 10, and adds that to the sum of the digits of the remaining places, num / 10 is the remaining places, and it calls sumOfDigits() on that number.
This method calculates sum of the numbers representing base 10 integer numbers. The method is called recursively with % operator to separate digits in the number and then add them to form the result.
Eg - 234 into 2 + 3 + 4 = 9
However, if you pass a integer in base other than base 10, the method still gives the result for base 10
Eg sumOfDigits(0b1011010) -> answer is 9 for 90 in base 10
sumOfDigits(0x532) -> answer is 7 for 1330 in base 10
Following is the change for binary and octal values to get the sum of the representing numbers
return num == 0 ? 0 : num % 2 + sumOfDigits(num / 2);
return num == 0 ? 0 : num % 8 + sumOfDigits(num / 8);
That's a Java ternary operator, but in most cases it is not used since if-else statements are much more readable, which can also do the same function ternary operators can do. But if you would like to make shorter code lines, then this is preferred.

Categories