mutually recursive functions - java

I am trying to understand why the below functions are outputting zero for any input I give them. I would have thought that based on the recursive nature that inputting a 2 to function g, would produce 12. Any integer I seem to use for either function simply outputs 0. Can anyone point to where I am going wrong in my thought process?
public class dsdsfsd {
public static int i(int n) {
if (n == 0) return 0;
return i(n-1) + g(n-1);
}
public static int g(int n) {
if (n == 0) return 0;
return g(n-1) + i(n);
}
public static void main(String[] args) {
int a = 2;
System.out.println(g(a));
System.out.println(i(a));
System.out.println(g(g(a)));
}
}

Sure. The only value these functions can return is 0. That's the base case, and the higher cases do nothing but add up those zeroes. Where do you see another value entering the equation?

If either function has zero as an argument, it returns 0.
If it has any other value, it returns the sum of two recursive calls.
The sum of two zeros is zero.
Where exactly do you expect the function to produce anything but zero?

Your problem is not on the recurrence but on the initialization of your variables.
I reckon that you try to calculate some linked coefficients by the formulas:
g(n) = g(n-1) + i(n)
i(n) = i(n-1) + g(n-1)
g(0) = 0
i(0) = 0
However, as you initialized g and i to 0, i(1) = g(0) + i(0) = 0 + 0 = 0, and any values of g(n) or i(n) will be 0 for the same reason which is: you keep adding 0's and 0's.
Instead if you want to have a non-null result you should change at least one of your initialization, for example:
g(0) = 1
i(0) = 1
That way, you have i(1) = g(0) + i(0) = 1 + 1 = 2 and g(1) = g(0) + i(1) = 1 + 2 = 3.
This is more a mathematical issue in the end.

You could reduce this to a single function for simplicity, since the mutual recursion is irrelevant:
public static int func(int n) {
if (n == 0) return 0;
return func(n-1);
}
Notice there are only 2 ways for this to return:
It can return 0 directly in the base case
It can return the result of recursing.
Think about that. At some point, it must stop recursing (or else it will run forever). What happens when the base case of 0 is returned? Your function turns into something like this (for imagining purposes only of course):
public static int func(int n) {
if (n == 0) return 0;
return 0;
}
Therefore, 0 is the only value your function(s) are capable of returning, since it's the only concrete value ever returned.

Related

Issue with recursion because thread suspension

I was playing around with a few practice problems in Java. I wrote a recursive program for program given below. My solution is right except for the suspended (which I believe) gets back to active state and changes the value of the recursive method. I have also added a screenshot of Eclipse in debug mode where the thread stack is shown.
package com.nix.tryout.tests;
/**
* For given two numbers A and B such that 2 <= A <= B,
* Find most number of sqrt operations for a given number such that square root of result is a whole number and it is again square rooted until either the
* number is less than two or has decimals.
* example if A = 6000 and B = 7000, sqrt of 6061 = 81, sqrt of 81 = 9 and sqrt of 9 = 3. Hence, answer is 3
*
* #author nitinramachandran
*
*/
public class TestTwo {
public int solution(int A, int B) {
int count = 0;
for(int i = B; i > A ; --i) {
int tempCount = getSqrtCount(Double.valueOf(i), 0);
if(tempCount > count) {
count = tempCount;
}
}
return count;
}
// Recursively gets count of square roots where the number is whole
private int getSqrtCount(Double value, int count) {
final Double sqrt = Math.sqrt(value);
if((sqrt > 2) && (sqrt % 1 == 0)) {
++count;
getSqrtCount(sqrt, count);
}
return count;
}
public static void main(String[] args) {
TestTwo t2 = new TestTwo();
System.out.println(t2.solution(6550, 6570));
}
}
The above screenshot is from my debugger and I've circled the Thread stack. Can anyone try and run the program and let me know what the problem is and what would be the solution? I could come up with a non recursive solution.
Your recursion is wrong, since the value of count will return in any case 0 or 1 even if it goes deep down into recursive calls. Java is pass by value, meaning that modifying the value of a primitive inside of a method wont be visible outside of that method. In order to correct this, we can write the following recursion:
private int getSqrtCount(Double value) {
final Double sqrt = Math.sqrt(value);
if((sqrt > 2) && (sqrt % 1 == 0)) {
return getSqrtCount(sqrt) + 1;
}
return 0;
}
Your code is wrong, you should have
return getSqrtCount(sqrt, count);
instead of
getSqrtCount(sqrt, count);
Otherwise the recursion is pointless, you're completely ignoring the result of the recursion.

Turn Positive into negative?

I've got this code
public class FiboNegativV {
int negativ(int nv) {
if (nv ==0)
return 1;
if (nv ==1)
return 2;
return negativ(nv-1) + negativ(nv-2);
}
}
Now I would like to turn the final number into negative. I've tried a few things like "nv = -nv;" But I usually got stackover when I put it before the
"return negativ(nv-1) + negativ(nv-2)" and it is unreachable when it's after this line.
You don't need function for that just do it like this:
int x *= -1;
All the other answers for some reason disregard your initial intention of a Fibbonacci sequence. But I do not understand why they do not keep the context. Your method obviously tries to do a Fibbonacci sequence with recursion yielding negative numbers.
Now I would like to turn the final number into negative.
The simplest and most intuitive way of negatinv a number is to use a unary minus operator = just add a minus before the expression (so negating x to -x). We use this only on positive numbers, so that the negative ones stay negative: (note: this is a ternary operator)
(result > 0) ? -result : result;
However the big mistake is that you do NOT handle negative numbers in the recursive method in the first place! Of course you run into stack overflow, because the recursive negative numbers are going to get lower and lower.
static int negativFib(int nv)
{
//turn negative input into positive
nv = nv < 0 ? -nv : nv;
//base cases
if (nv == 0)
return 1;
if (nv == 1)
return 2;
final int result = negativFib(nv - 1) + negativFib(nv - 2);
//turn the number into negative
return result > 0 ? -result : result;
}
Alternative algorithm
An another problem which could occur is that with big numbers, the recursion comes to a stack overflow. You could prevent this by using some other algorithm, f.e. dynamic programming. With dynamic programming Fibbonacci sequence you store the previous 2 results every time and solve the problem in iterations, instead of recursion.
If you only want to convert positive into negative then
nv = (nv > 0) ? nv * -1 : nv
if you want to convert positive to negative and negative to positive then
nv = nv * -1
Below your code will look like
public class FiboNegativ
{
public FiboNegativV(){}
int negativ(int nv)
{
return (nv > 0) ? nv*-1 : nv;
}
}
Since you want only the final number to be negative, the easiest way is to work with absolute numbers, and return negative numbers, as per the following:
public class FiboNegativV {
int negativ(int nv) {
return (nv == 0) ? -1 :
(nv == 1) ? -2 :
-(Math.abs(negativ(nv-1)) + Math.abs(negativ(nv-2)));
}
}
The assumption I have made, above, is that the initial input to the function will always be positive. Your original code confirms this assumption.
-1 * (Math.abs(negativ(nv-1) + negativ(nv-2)));
Thus the result will be negative regardless of the values given.

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

recursive to iterative (java)

as a beginner in programming I am trying to convert the following recursive method to an iterative one but I just don't get the hang of it. The method or function has a binary tree like recursion and I would like to use an array for the iterative solution.. unfortunately I am very confused how to do it.
I have already checked the way of converting the fibonnaci recursive method to an iterative one. But I think this is not the same here. Also I am not sure if a tree search method is useful?! Any help, hint, idea would be appreciated. Thanks.
public static int funct(int n) {
if (n == 0) return 1;
if (n == 1) return 2;
if n > 1 return funct(n-2)*funct(n/2);
}
Since every n-th member is computed by others before if you can cache all in a list. You start by adding the first 2 known members. Fibonacci its easier because you always need only previous value.
private static int func(int n) {
List<Integer> values = new ArrayList<>(n+1);
values.add(1);
values.add(2);
for (int i = 2; i <= n; i++) {
values.add(values.get(i - 2) * values.get(i / 2));
}
return values.get(n);
}
Now the real function is without last if:
public static int funct(int n) {
if (n == 0) return 1;
if (n == 1) return 2;
return funct(n-2) * funct(n/2);
}
As the recursive calls refer to smaller parameters one can cache all return values upto n.
Unfortunately this already spoils the pleasure, as the resulting code is complete:
public static int funct(int n) {
int[] results = new int[n+1];
results[0] = 1;
results[1] = 2;
int i = 2;
while (i <= n) {
results[i] = results[i-2] * results[i/2];
++i;
}
return results[n];
}
It indeed looks like fibonacci.
In general one would not need to fill all items of results. like probably results[n - 1].
Unfortunately you should have learnt prior to this problem:
Solving tail recursion.
Using a stack (like here) to use inner results of a recurive call.
You might look into those topics.
Math afterlude
The initial values are powers of 2. As the result is a product of earlier results, all results will be powers of 2.
f(0) = 1 = 2^0
f(1) = 2 = 2^1
f(n) = f(n - 2) * f(n / 2)
Hence you can introduce:
g(0) = 0
g(1) = 1
g(n) = g(n - 2) + g(n / 2)
f(n) = 2^g(n)
This will enlarge the range you can calculate as say 2100.
You will also see:
g(2k + 1) = g(2k) + 1
So you will only need a domain of even numbers:
g(2k) = g(2(k-1)) + g(k - k%2) + k%2

Fibonacci recursion ex

Again, I'm still working with recursion, I've got a question regarding one of the base cases.
UPD: a and b represent the 1st numbers in the sequence and n is the desired position for the to-be calculated sum.
My code is as follows:
public static int fib(int a, int b, int n) {
if (n <=1) {
return a;
} else if (n == 2) {
return b;
} else {
return (fib(a, b, n - 1) + fib(a, b, n - 2));
}
}
In Line 2, before i started tracing out the program by hand, i kept it as "n<=0" . However, I got a diff answer as i traced and run the program. The problem was at some point n will = to 1. So I changed the first base case to n<=1 and got same answers.
Now the question is, suppose I called the method as follows: fib(2,3,6)
the answer should be = 21 ( with line 2 = " n<=1")
but when line 2 was "n<=0" the answer was 27.
I would like to know what happens to the program when n eventually = 1 given "n<=0" in Line 2
The call when n is 1 will generate two extra recursive calls with n as 0 and n as -1. These two recursive calls will add a twice to the correct answer.
To get the nth Fibonacci, simply pass n to the function.
Assuming the sequence is 0, 1, 1, 2, 3 ...
Your algorithm will be
if n = 1 return 0
else if n = 2 return 1
else return fib(n - 2) + fib(n - 1)
I actually answered my own question.
You see at some point n = 3,
So the value to be returned will eventually lead to n =1 as follows:
return (Fib(2,3,2)+ Fib(2,3,1))
Now that n = 1 the base case in Line 2 will be executed properly.
whereas if the base case in Line 2 was " n<=0" then for the case of n =3
return (Fib(2,3,2) + Fib(2,3,1))
then Fib(2,3,1) will cause the method to be called again and will result to n =0 and that will lead to having n = -1 & n =-2 causing the answers to differ.
//UpDATED: having n =0 & n=-1 will cause the answers to differ
You have two base cases where both will hit eventually and instead of returning n which would be correct it returns one of the passed and unchanged variables a or b.
Your code is a messy combination of the two different ways of computing the fibonacci series.
You have the recursive one that is very inefficient:
public static int fib(int n) {
if (n <=1)
return n;
return fib(n-1) + fib(n-2);
}
But, as you see it will compute everything severeal times. If you see the sequence you can iterate from the beginning by having two numbers, a and b, as arguments:
a 0 1 1 2 3 5 ...
b 1 1 2 3 5 8 ...
To compute the next a, you use b. To compute the new a you add a and b. Thus a more efficient algorithm is:
public static int fib(int a, int b, int n) {
if (n <= 0)
return a;
return fib(b, a+b, n-1);
}
Java does not tail call optimize so recursion won't work as well as in other languages that does optimize tail calls, thus an non recursive version of this would be better, like:
public static int fib(int n) {
for(int a=0, b=1;; n--) {
if (n <= 0)
return a;
int tmpa = a;
a = b;
b += tmpa;
}
}

Categories