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
Related
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.
public int bunnyEars(int n) {
if (n < 0) {
throw new IllegalArgumentException();
}
if (n == 0) {
return n;
}
if (n % 2 == 1)
return 2 + bunnyEars(n - 1);
return 3 + bunnyEars(n - 1);
}
can someone explain how bunnyEars(2) = 5
and also how it works?
If the number n is less than 0, then an IllegalArgumentException is thrown, as evidenced by:
if (n < 0) {
throw new IllegalArgumentException();
}
So, we know n is always supposed to be 0 or greater. We also know that the method is supposed to return when n is equal to 0, as evidenced by:
if (n == 0) {
return n;
}
So, presumably, the method public int bunnyEars(int n) will take a number equal to or greater than zero, and will start adding integers until the n is zero.
We see two different possible scenarios to take n's greater than zero and do something with them:
if (n % 2 ==1)
return 2 + bunnyEars(n-1);
return 3 + bunnyEars(n -1); //else
What is happening here is if the n % 2 is equal to one (meaning that the number is odd, since every odd integer divided by two has a remainder of one), then the method is recursively called with the current n minus 1, and the final integer to return is incremented by two.
If the number is not odd (and is thus even), then the same thing is happening, but with the final integer to return incremented by 3.
So in your example of bunnyEars(2), we see that the n of 2 is both positive and greater than zero, so no error is thrown and the method does not return without recursion. Since 2 is an even number (2 % 2 is 0), the second return is used. This means that 3 + bunnyEars(1) is called.
Since 1 is also greater than 0, we go to the recursive methods again. Since 1 is an odd number (1 % 2 is 1), the first recursive return is called. This means we call 2 + bunnyEars(0).
Now, since n is 0, the return n from the if-statement is used:
if (n == 0) {
return n;
}
On the first round we had the final integer to return incremented by 3, and on the second time it was incremented by 2, for a total of 5. So the result is five.
From your comments, I understand that you already know the meaning of a recursive call. In order to make it clear how it works, you can trace the calls in some way. Given below is an example of one of the ways:
public class Main {
public static void main(String[] args) throws InterruptedException {
System.out.println(bunnyEars(2));
}
static int bunnyEars(int n) {
if (n < 0) {
throw new IllegalArgumentException();
}
if (n == 0) {
System.out.println(n);
return n;
}
if (n % 2 == 1) {
System.out.print("2 + bunnyEars(" + n + "-1) -> ");
return 2 + bunnyEars(n - 1);
}
System.out.print("3 + bunnyEars(" + n + "-1) -> ");
return 3 + bunnyEars(n - 1);
}
}
Output:
3 + bunnyEars(2-1) -> 2 + bunnyEars(1-1) -> 0
5
As you can see, 3 + 2 + 0 = 5 is what you get as the answer.
I hope, it helps. Feel free to comment in case of any doubt.
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.
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.
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.