Tracing through a recursive function [closed] - java

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 7 years ago.
Improve this question
For the following code segment, I am having trouble tracing through it (which I need to be able to do for my upcoming test.
public int question(int x, int y)
{
if (x ==y)
return 0;
else
return question(x-1, y) + 1;
}
I am also confused as to what the + 1 is doing. What is 1 being added on to. I know the result is five, but I need to be able to better understand the concept. Thanks for your help.

Basically:
question(8,3) will return question(7,3) + 1
question(7,3) will return question(6,3) + 1
question(6,3) will return question(5,3) + 1
question(5,3) will return question(4,3) + 1
question(4,3) will return question(3,3) + 1
and question(3,3) is 0.
It should be obvious that the result of question(8,3) is 5 by simple substitution. It should be noted that if x < y then you might get a stack overflow as x keeps decrementing and will possibly never get to x == y.

the 1 is being added onto the return from the function every time the function recurses 1 is added onto the return of int
public int question(int x, int y)
{
if (x ==y)
return 0;
else
return question(x-1, y) + 1;
}
say you call
int result = question(5,0);
since your general case calls
return question(x-1, y) + 1;
the + 1 is going to recurse until you hit the base case of
if (x ==y)
return 0;
giving you +1 +1 +1 +1 +1 +0
until x = 0 and y = 0

You can always add a couple prints to the method to better understand what it is doing:
static int question(int x, int y) {
if (x ==y) {
System.out.println(x + " == " + y);
System.out.println("return 0");
return 0;
} else {
System.out.println(x + " != " + y);
System.out.println("call question(" + (x - 1) + ", " + y + ")");
int result = question(x - 1, y);
System.out.println("return " + result + " + 1");
return result + 1;
}
}
Then call it. For example:
public static void main(String... args) {
System.out.println(question(8, 3));
}
Output:
8 != 3
call question(7, 3)
7 != 3
call question(6, 3)
6 != 3
call question(5, 3)
5 != 3
call question(4, 3)
4 != 3
call question(3, 3)
3 == 3
return 0
return 0 + 1
return 1 + 1
return 2 + 1
return 3 + 1
return 4 + 1
5

In order to understand recursion, try to write function in a mathematical way. I will first demonstrate this with the classic factorial, then explain you the example you gave.
Let fact(n) be n!. The recursive definition of factorial is:
fact(n) = 1, if n <= 1
fact(n) = n * fact(n - 1)
Note that we have 2 cases: a base case, which is a simple case that can be calculated directly, and a step case, which requires the value of a recursive call. Note that in order for the recursion to work, the recursive function call should be simpler, in order to move towards the step case. This can be implemented easily in Java:
public int factorial(int n)
{
if (n < 2)
return 1;
else
return n*factorial(n-1);
}
Returning to your function, you have to do the same process backwards. We can easily identify the 2 base cases as the branches of if:
Base case: question(x, y) = 0, if x = y
Step case: question(x, y) = question(x - 1, y) + 1, otherwise
It can be noticed that at each recursive call you subtract 1 from x and add 1 to the result. Let's unroll the recursion for question(8, 3):
question(8, 3) = question(7, 3) + 1 // You are in the step case
question(7, 3) = question(6, 3) + 1
question(6, 3) = question(5, 3) + 1
question(5, 3) = question(4, 3) + 1
question(4, 3) = question(3, 3) + 1
question(3, 3) = 0 // The base case
Now, if you replace the value of question(3, 3) in the value of question(4, 3) and do the same upwards, you find out that the result is 8.
There is no straight way to do this, but you can notice that the first parameter is decreasing by 1 and each time this is done, the result increases by 1, until the parameters are equal. Using some intuition, you may notice that this basically computes x - y.
Note that this method requires x >= y, otherwise it will crash.

Related

Java simple recursion explanation

I was implementing a very simple recursive method to multiply two numbers together. I am very a hard time understanding the basics of recursion.
Is anyone able to explain to me (Line-by-line if possible) how this code works? I am especially confused about the base case is written to return 0 when in reality the actual multiplication is returned instead.
public static int multiply(int n, int m) {
if (m == 0) {
return 0; //Base case
}
return multiply(n, m - 1) + n; //Recursive Case - Decrements m, while adding n
}
Thanks for any help
I will try to make this answer beginner friendly. First I will answer this part of your question:
I am especially confused about the base case is written to return 0
when in reality the actual multiplication is returned instead.
The value returned in the base case depends on how you are implementing your algorithm. Here in order to calculate n*m, we extend this multiplication to addition. A few examples will make this more clear.
2*3 = 2 + 2 + 2 + 0
4*1 = 4 + 0
5*5 = 5 + 5 + 5 + 5 + 5 + 0
n*m = n + n + n + ... + (m times) + 0
That is why we return 0 in the base case, we have to stop the recursion without making any change in the result and that is only possible if we add 0.
Here is the working of this program:
public static int multiply(int n, int m) {
if (m == 0) {
return 0; //Base case
}
return multiply(n, m - 1) + n;
Let us take n = 4 and m = 3.
Our first call to the method is multiply(4, 3). We then proceed further, the base condition is false so we skip that.
We then get to this part: return multiply(n, m - 1) + n. We make another call to the same function. multiple(4, 2). Again we skip the base case. Here is a table:
multiply(4, 3) -> return multiply (4, 2) + 4
multiple(4, 2) -> return multiply (4, 1) + 4
multiple(4, 1) -> return multiply (4, 0) + 4
multiple(4, 0) -> 0
On substituting the returned values we get,
multiple(4, 3) -> return 0 + 4 + 4 + 4
multiple(4, 2) -> return 0 + 4 + 4
multiple(4, 1) -> return 0 + 4
multiple(4, 0) -> return 0
If our first call is multiply(n, m), then the end returned value is:
multiply (n, m) -> return 0 + n + n + n + ... + (m times)
I hope I have helped you. Try to construct a similar relation like this on your own and you will understand it better. Here is a link on further explanation on recursion:
https://www.geeksforgeeks.org/recursion

Exercise java recursion

I don't understand how this exercise return the number's square. In particular I don't understand the sixth line in which there is return statement and after this "+2*x-1". What is the program behavior in that call?
public class Es {
public static int RecCalc(int x) {
if (x==0) {
return 0;
}else {
return RecCalc(x - 1) + 2 * x - 1;
}
}
public static void main(String[] args) {
System.out.println(RecCalc(3));
}
}
We can see how this works with a little algebra:
(x-1)² + 2x - 1
== x² - 2x + 1 + 2x - 1
== x²
If you are unfamiliar with the formula for (x + y)² then you can do (x-1)² by writing it as (x-1)*(x-1) and using the FOIL method or the distributive property. This is left as an exercise for the reader.
Let's step through, one call at a time.
The first call to kick it all off is:
RecCalc(3);
In Java, the return statement will take everything up to the semi-colon.
So, return 3 + 2 will return 5 to the caller.
RecCalc(3) will result in calling:
RecCalc(2) + 2*3 -1;
RecCalc(2) will result in calling:
RecCalc(1) + 2*2 -1;
RecCalc(1) will result in calling:
RecCalc(0) + 2*1 - 1;
RecCalc(0) will return 0.
Now we can work our way back up the call stack.
RecCalc(0) == 0
RecCalc(1) == RecCalc(0) + 2*1 -1 == (0) + 2*1 -1 == 1
RecCalc(2) == RecCalc(1) + 2*2 -1 == (1) + 2*2 -1 == 4
RecCalc(3) == RecCalc(2) + 2*3 -1 == (4) + 2*3 -1 == 9
This doesn't explain the math, but explains the recursion.
Let's look at the math.
As explained by #CodeApprentice, x² = (x-1)² + 2x -1
The real trick to this whole recursive scheme is the (x-1)².
We know that for x = 4, we can use (x-1)² plus some other junk to get the answer.
But that's just the square of 3 plus some other junk!
Now, to get the square of 3, we know that 3² = (x-1)² plus junk.
But that's just the square of 2 plus some other junk!
And so, we work our way down until we get to a trivial answer, where we return 0. (In fact, you could also return 1 for x=1).
I hope that explains it!
If you have 4 things, you can make a square with side 2:
xx
xx
If you want to make a square with side 3, you need 9 things: add 2 things on each of the side and bottom, plus 1 for the corner:
xx.
xx.
..+
Or, to put it another way, add 3 things on each of the side and bottom, take away 1 for the corner.
Generalizing, if you have a square of side length (n-1), to make a square of side length (n), you have to add on 2 lots of (n-1) things, plus one; or 2 lots of (n) things, take away one.
Hence:
number of things in a square of side length n
= (number of things in a square of side length (n-1))
+ 2 * (n-1) + 1
= (number of things in a square of side length (n-1))
+ 2 * n - 1
Perhaps if you put in a print statement it will help.
public static void main(String[] args) {
System.out.println(RecCalc(5));
}
public static int RecCalc(int x) {
if (x == 0) {
return 0;
} else {
int v = RecCalc(x - 1) + 2 * x - 1;
System.out.println((x-1) + " " + (2*x) + " " + (-1));
return v;
}
}
Prints
0 2 -1
1 4 -1
2 6 -1
3 8 -1
4 10 -1
25
Notice that the value of the sum of the last two columns in each line is an odd number. And the sum of any number of consecutive odd numbers starting with 1 is a perfect square. So essentially, this method just sums up the first x odd numbers.

Java Order of Operation

I am having some problems understanding stacks and order of operations in java. If I had the following:
operation(7, 2)
public int operation(int x, int y) {
if (x == y)
return 0;
else
return operation(x – 1, y) + 2;
}
What would be the result? I am being told that it should be a single number result but I don't understand how (x – 1, y) + 2 can be single number. I have gotten it to:
(x – 1, y) + 2
(7 - 2, 2) + 2
(5, 2) + 2
But I don't understand the method for adding the 2 at the end. Wouldn't this need to return both values separated by a comma?
Wouldn't this need to return both values separated by a comma?
Nope.
operation(x – 1, y) + 2 is a recursive function.
operation(7 - 1, 2) + 2 => operation(6, 2) + 2 This calls the operation function with arguments 6 and 2 (similar to how you did the initial call). This call will eventually end up with a number to which 2 is added and returned.
Taking a smaller number for better visualization operation(4, 2)
operation(4, 2) -> return operation(3, 2) + 2
operation(3, 2) -> return operation(2, 2) + 2
operation(2, 2) -> return 0 (the base case)
.. stack unwinds
operation(3, 2) -> return 0 + 2
operation(4, 2) -> return 2 + 2
operatation(7, 2) returns -> 8 + 2 = 10
operatation(6, 2) returns -> 6 + 2 = 8
operatation(5, 2) returns -> 4 + 2 = 6
operatation(4, 2) returns -> 2 + 2 = 4
operatation(3, 2) returns -> 0 + 2 = 2
operatation(2, 2) returns -> 0
The recursive calls will be made till the x and y values equal, in that case operation returns 0. The return value is then added to 2 and returned to caller i.e. 0 + 2 = 2 and so on, till the first caller is returned. Hence the answer is 10.
This ends up being roughly equivalent to a for loop, actually. This code has the exact same result as operation(7, 2):
int equivOfOperation = 0;
for (int i = 2; i < 7; i++)
{
equivOfOperation += 2;
}
The recursive function will end up doing the equivalent of
for (int i = y; i < x; i++)
assuming, of course, that y < x. (In this case, operation would end up with infinite recursion).
Since several of the other answers have already shown the trace of the recursion, I won't repeat that here, but you might want to walk through their traces and convince yourself of this having the same effect as a for loop.

How to read recursion methods accurately

I'm preparing for a java programming exam that's coming up in a few days and I've been tryna get my head around this:
The initial starting value of int num is 8
public int func1(int num)
{
if(num <=1) return 1;
return num + func1 (num - 3);
}
How do you go through through the return num + func1 (num - 3) part?
I don't get how that line of code works
I hope this will help you understand recursion.
return 8 + func1(5)
return 8 + 5 + func1(2)
return 8 + 5 + 2 + func1(-1)
return 8 + 5 + 2 + 1
and finally returns like
return 8 + 5 + 3
return 8 + 8
return 16
Easiest way to understand recursion is
Assume that the whole public int func1(int num) is inserted in the return
so ur function returns somewhat in this way
return 8 + func1((8) - 3) // i.e return 8 + func1(5)
return 8 + 5 + func1((5) - 3) // i.e return 8 + 5 + func1(2)
return 8 + 5 + 2 + func1((2) - 3) // i.e return 8 + 5 + 2 + func1(-1)
return 8 + 5 + 2 + 1
So total will be 16
Just trace through it the exact same as for any other method call. It's just calling itself which is another way to do a loop.
i.e.
func1(8)
calls func1(8-3)
calls func1(5-3)
calls func1(2-3)
returns 1 as -1 < 1
returns 2+1
returns 5+3
returns 8+8
So the final result is 16.
"The only way to understand recursion is to understand recursion".
Now seriously, you need to think of the execution of a recursive program as a stack with a basic case and a general case:
For instance the factorial method:
Basic case: f(n) = 1, if n = 0.
General case: f(n) = n*f(n-1), otherwise.
Result would be:
f(n) = n*f(n-1)
f(n-1) = (n-1)*f(n-2)
...
f(2) = 2*f(1)
f(1) = 1*f(0)
f(0) = 1
Basically you need to go down until the basic case and then reconstruc the result via the partial results you are finding.
Recursive algorithms are very useful for some methods which otherwise would require lots of memory to store intermediates value.

fault or error in this method

I am revising for a software testing exam. One of the questions gives this method and asks to identify the fault as well as produce a test case (if one exists) which does not execute the fault.
Here is the code:
public static int oddOrPos(int[] x) {
//Effects: if x==null throw NullPointerException
// else return the number of elements in x that
// are either odd or positive (or both)
int count = 0;
for (int i = 1; i < x.length; i++)
{
if (x[i]%2 == 0 || x[i] > 0)
{
count++;
}
}
return count;
}
I have identified two problems. One being that i is initialised to 1 in the for loop so x[0] doesn't get tested. Also x[i] % 2 == 0 should be x[i] != 0
Are these problems faults or errors? I ask this because the question makes it appear that there is only one fault.
Also, I assume that because the for loop will always be executed, there is no test case which will not execute the fault.
Actually x[i] % 2 == 0 should be x[i] % 2 != 0 (if we want to detect odd values along with the positive ones. The existing code will detect even values instead).
The test case is just { -2 } - this element is even and negative, so should not get counted, and the method will return 0 even though it is faulty. { 1 } will also give 0, which is wrong.
If you want to detect odd negative values you'll have to look for -1 and not for 0 as it's done right now.
For odd positive values it will be 1. So basically you want anything but 0.
The % operator is a remainder operator, not really a modulo operator, it returns a negative number if the first given number is negative:
class Test1 {
public static void main(String[] args) {
int a = 5 % 3; // 2
int b = 5 / 3; // 1
System.out.println("5%3 produces " + a +
" (note that 5/3 produces " + b + ")");
int c = 5 % (-3); // 2
int d = 5 / (-3); // -1
System.out.println("5%(-3) produces " + c +
" (note that 5/(-3) produces " + d + ")");
int e = (-5) % 3; // -2
int f = (-5) / 3; // -1
System.out.println("(-5)%3 produces " + e +
" (note that (-5)/3 produces " + f + ")");
int g = (-5) % (-3); // -2
int h = (-5) / (-3); // 1
System.out.println("(-5)%(-3) produces " + g +
" (note that (-5)/(-3) produces " + h + ")");
}
}
Another "small" fault is the way the condition is done. Instead of checking for odd or positive, looking for positive or odd will be slightly faster. It's only because it's easier to check if a number is positive or not than getting its remainder.
Resources:
15.17.3. Remainder Operator %
The major thing here is that your for loop is starting at 1, and it should start at 0. You will always miss the first element of the array. Also x[i]%2 == 0 returns true for even numbers, not odd. So change that to x[i]%2 != 0.
public class test{
public static void main(String[] args){
int[] x = {3, 5, -1, -14}
if( 3 == oddOrPos(x)){
System.out.println("Working");
else
System.out.println("Test Fail");
}
public static int oddOrPos(int[] x) {
//Effects: if x==null throw NullPointerException
// else return the number of elements in x that
// are either odd or positive (or both)
int count = 0;
for (int i = 0; i < x.length; i++)
{
if (x[i]%2 != 0 || x[i] > 0)
{
count++;
}
}
return count;
}
}
As I understand it, you are right in your assumption. The first position of the array should be tested, hence the i[0] you pointed out.
However, x[i]%2 == 0 should instead be x[i]%2 == 1 for an odd number.

Categories

Resources