I'm currently working my way through the Java tutorials and am currently on Recursions.
I have the following code which calculates the factorial of any number passed to the factorial method
public class App {
public static void main(String[] args) {
//E.g 4! = 4*3*2*1(factorial 4)
System.out.println(factorial(4));
}
private static int factorial(int value){
//System.out.println(value);
if (value == 1){
return 1;
}
return factorial(value - 1)*value;
}
}
I have trouble understanding the part
if (value == 1){
return 1;
}
return factorial(value - 1)*value;
My understanding is that the return keyword simply terminates the method, and/or returns a value of the same type declared by the method(i.e int,String, etc).
What happens when the following line is run?
return factorial(value - 1)*value;
the function is returning the total of (value - 1) * value, which would give me
(3)*4 = 12
(2)*3 = 6
(1)*2 = 2
with each passing iteration.However, System.out.println(factorial(4)); gives me a total of 24. How is this number derived from the method? There are no variables to store the sum of the values, so where is the program storing them? Also, how do I get 24 from these values?
(3)*4
(2)*3
(1)*2
While I know that 24 is derived from 4*3*2*1, I do not see how that can be calculated from the above.
Any explanation would be greatly appreciated.
You've misinterpreted
return factorial(value - 1)*value;
The values being multiplied are factorial(value - 1) and value. In other words, you can rewrite it like this:
return (factorial(value - 1)) * value;
So when you pass 4, you get this:
factorial(3) * 4;
which is equivalent to
(factorial(2) * 3) * 4;
which is equivalent to
((factorial(1) * 2) * 3) * 4;
which is equivalent to
1 * 2 * 3 * 4;
The way this works, which you can see easily if you step through the code with a debugger, is as follows:
The first call to the function passes 4. The function evaluates the if, then calls itself, passing 3. (The state of the first function call is preserved on the stack, so when this call returns, we can resume where we left off, now that we have the result of the function call. This "stack" abstraction is not actually necessary to understand recursion.)
The second function call evaluates the if and calls itself, passing 2.
The third function call evaluates the if and calls itself, passing 1.
The fourth function call evaluates the if and returns 1.
The third function call then resumes, multiplying the return value of the function that just returned (1) with the value of its argument (2), returning the result (2).
The second function call then resumes, multiplying the return value of the function that just returned (2) with the value of its argument (3), returning the result (6).
The first function call then resumes, multiplying the return value of the function that just returned (6) with the value of its argument (4), returning the result (24).
Some optimizing compilers will change recursive calls into loops, but it's not generally possible to change a recursive call to a fixed expression, like 1 * 2 * 3 * 4, because at compile time you don't generally know how deep the recursion will be.
All of this will be abundantly clear if you modify your code as follows and then step through it with a debugger:
private static int factorial(int value){
if (value == 1){
return 1;
}
int recursiveResult = factorial(value - 1);
return recursiveResult * value;
}
Note that with each recursive call, we have to store the state of a "suspended" method, waiting for the result of the call, on the stack. For this reason, if a method calls itself recursively (or a chain of methods call themselves in mutual recursion), there is a possibility for the stack to become full. This is known as a stack overflow. It is usually caused by incorrect logic in a function causing a recursive loop:
int stackOverflow() { return stackOverflow(); }
It can also be caused by a function that doesn't logically loop, but calls itself too many times because of the data passed to it. For example, recursive functions are useful when working with tree data structures; if the tree is too tall, it can cause a stackoverflow. So will the following, with some arguments, but not with others:
void possibleStackOverflow(int arg) { if (arg == 0) return; possibleStackOverflow(arg - 1); }
If you call possibleStackOverflow(10) you're probably fine, but possibleStackOverflow(-1) will throw an exception.
Also, by VM implementation limitations, calling possibleStackOverflow(Integer.MAX_VALUE) will throw an StackOverflowException
Your return clause is returning the result of factorial(value-1)*value each factorial(value-1) will be replaced by the result of the method call.
This means factorial(4) is:
(factorial(1) * (factorial(2 -1) * (factorial(3 -1) * factorial(4 - 1)))) * 4
This will be
(1 * (2 * 3)) * 4 that is 24
return factorial(value - 1)*value;
Returns the factorial of value - 1 times value.
It goes like this:
factorial(4)
=factorial(3) * 4
= factorial(2) * 3 * 4
= factorial(1) * 2 * 3 * 4
= 1 * 2 * 3 * 4 = 24
To understand recursion try to draw a tree of the calls and the parameters:
factorial(4) = 4 * factorial(4-1)
|
3 * factorial(3-1)
|
2 * factorial(2-1)
|
1
Try it with the recursive fibonacci formula.
The word 'return' does, indeed, break from the current method and return a value/result. However, you have an 'expression' in the return 'statement' that needs to be evaluated before 'return' can exit.
For example, return 1 + 1; needs to evaluate the operation '+' before it returns.
When you call return func(arguments); java has to call that function before it returns. In this case, it recursively goes through this "call stack" (function calls are put on a 'stack' where the last one in is the first evaluated).
So, to really describe what is going on here:
1) return statement recognizes an expression
2) the expression calls a function on the stack
3) the function on the stack hits another return with another function to evaluate
4) ...
5) the "base case" is reached, where a '1' is found.
6) the function calls are executed down the stack to evaluate the expression
Your recursive method can end in only two ways. Either value is 1 and it returns 1, or it calls itself with a smaller value-1 and returns the product of whatever that result was and the current value.
The method could have been written more expanded like this:
private static int factorial(int value){
if (value == 1){
return 1;
}
int a = factorial(value - 1);
return a * value;
}
From a stack point of view it looks like this. I've inserted fictitious variables a, b and c to indicate the value of the recursive calls as they return.
factorial(4)
|-- a = factorial(4-1=3)
| |-- b = factorial(3-1=2)
| | |-- c = factorial(2-1=1)
| | | +-- return 1 // <-- deepest point in the stack
| | +-- return c * 2 = 2
| +-- return b * 3 = 6
+-- return a * 4 = 24
If you put a larger starting number, the stack would just get deeper, repeatedly calling factorial(value-1) until it finally got to 1 and then the stack unwinds to reveal the answer. If you put much much larger number, you will end up with a stack overflow (the namesake of this site!) because you'd run out of memory to hold all of the variables needed.
Java uses the stack to store information between recursive calls. See https://en.wikipedia.org/wiki/Call_stack for more info.
As I thought, return f(); means execute f() and return the result of f().In recursion , return result; is just a program statement runs after recursion function f(). So it's execution order is contrary to modulated recursion function.
Related
So I was doing a recursion challenge on codingbat and came across the "bunny ears" problem where we have a number of bunnies and each bunny has two big floppy ears. We want to compute the total number of ears across all the bunnies recursively (without loops or multiplication).
The solution apparently is quite simple:
public int bunnyEars(int bunnies)
{
if(bunnies == 0)
return 0;
return 2+bunnyEars(bunnies-1);
}
But I am not able to understand. If we pass 2 in the bunnyEars(2) method the
recursive part bunnyEars(bunnies-1); should have 1 left in the bracket after subtraction and thus 2+(1); which should be equal to 3 and not 4.
But the output comes as 4. So how does recursion actually work in this code?
It is not 2+(1), it is 2+numberOfEarsOfBunnies(1) == 2+2.
I renamed the function a little to make it more obvious.
Or even more into detail:
numberOfEarsOfBunnies(2)==
2+numberOfEarsOfBunnies(1)==
2+(2+numberOfEarsOfBunnies(0))==
2+(2+0)==
2+2==
4
if we pass 2 in the bunnyEars(2) method the recursive part bunnyEars(bunnies-1); should have 1 left in the bracket after subtraction and thus 2+(1); should be equal to 3 and not 4.
It seems you're misreading the expression. The line of code in question says
return 2+bunnyEars(bunnies-1);
Now you call bunnyEars(2), so bunnies == 2; and then you reach this line of code.
return 2+bunnyEars(bunnies-1);
resolves to
return 2+bunnyEars(2-1);
or
return 2+bunnyEars(1);
So a second instance of the bunnyEars() function starts running, with bunnies == 1. It reaches that same line of code, and this time
return 2+bunnyEars(bunnies-1);
is
return 2+bunnyEars(1-1);
or
return 2+bunnyEars(0);
So a third instance of bunnyEars() gets running, with bunnies == 0; but this matches your base case, so you just return 0 ; this time we don't recurse. So back up a level we find that
return 2+bunnyEars(0);
is
return 2+0; // because bunnyEars(0) returned 0
so that instance returns 2. And that means
return 2+bunnyEars(1);
becomes
return 2+2; // because bunnyEars(1) returned 2
And of course 2+2 is 4, the correct answer.
It seems as though you applied the -1 to the return value of the recursive bunnyEars() call, but the code says to apply it to the parameter you're sending in, not to the return value.
I'm still wrapping my mind around recursion, and I think I get basic ones like factorial. But I'd like further clarification when the return statement is a little more complex like on the following snippet:
/**
* #param n >= 0
* #return the nth Fibonacci number
*/
public static int fibonacci(int n) {
if (n == 0 || n == 1) {
return 1; // base cases
} else {
return fibonacci(n-1) + fibonacci(n-2); // recursive step
}
}
In the return statement, does the fibonacci(n-1) completely recur through, before going down the fibonacci(n-2) step (does that make sense)? If so, this seems very difficult to envision.
Yes, one invocation will recurse all the way down and return, before the other one starts executing.
The order of invocation in Java is well-defined: fibonacci(n-1) goes before fibonacci(n-2).
Edit: Since the question originally included [C++] tag, here is the C++ part of the story: one of the two invocations still has to complete before the other one starts to run, but which one, fibonacci(n-1) or fibonacci(n-2), is unspecified.
Since the function has no side effects, it does not matter which of the two invocations gets to run first. The only thing that is important for understanding of recursion is that both invocations must complete, and their results must be added together, before the invocation at the current level returns.
It isn't much more different than calling a different function than itself. It needs to finish before the calling function can do anything with the result.
finobacci(0); // ==> 1 (since n is zero, the base case is to return 1)
fibonacci(1); // ==> 1 (since n is one, the base case is to return 1)
Now lets try 2 which is not the base case:
fibonacci(2); // == (since it's not the base case)
fibonacci(1) + fibonacci(0); // == (both calls to fibonacci we already haver done above)
1 + 1 // ==> 2
So in reality what happens is that the call to fibonacci2 waits while each of the two recursive calls to finish, just like a function that does System.out.println would wait until it had printed the argument before continuing to the next line. Recursion isn't that special.
Trivia: This is the original series from Fibonacci himself. Modern mathematicians start the series with n as the base case result making the series 0, 1, 1, 2, ... rather than 1, 1, 2, 3, ....
it works in this way:
Fibonacci program:
public int fibonacci(int n) {
if(n == 0)
return 0;
else if(n == 1)
return 1;
else
return fibonacci(n - 1) + fibonacci(n - 2);
}
Explanation:
In fibonacci sequence each item is the sum of the previous two. So, as per recursive algorithm.
So,
fibonacci(5) = fibonacci(4) + fibonacci(3)
fibonacci(3) = fibonacci(2) + fibonacci(1)
fibonacci(4) = fibonacci(3) + fibonacci(2)
fibonacci(2) = fibonacci(1) + fibonacci(0)
Now you already know fibonacci(1)==1 and fibonacci(0) == 0. So, you can subsequently calculate the other values.
Now,
fibonacci(2) = 1+0 = 1
fibonacci(3) = 1+1 = 2
fibonacci(4) = 2+1 = 3
fibonacci(5) = 3+2 = 5
In multiple recursion the program calls itself with its first call until the base case is reached, in this case fibonacci(n-1); after that the recursion stops and return his value to continue calling the value to the second part of the recursion fibonacci(n-2).
If you don't visualize the multiple recursion in the program, this
fibonacci recursion tree may be helpful.
A simple code snippet calculating the factorial of a number below:
public class Main{
static int factorial(int number){
System.out.println("At factorial("+number+")");
if (number == 1){
return 1;
}
return number * factorial(number-1);
}
public static void main(String[] args){
System.out.println("factorial(4) = "+ factorial(4));
}
}
Here, I thought that when the value of the number becomes 1(due to recursion), it returns 1 every time and breaks out of the method and prints 1. But, it does return proper factorial value?
As per this: Java - Does returning a value break a loop?, shouldn't it have returned 1 every time? How these 2 code snippet differ in returning a value?
Thank You
I have tried to explain the whole process; refer to this source.
Prior to this you should have basic understanding of call stacks, recursion, and stack frames.
A call stack is a data structure used by the program to store information about the active subroutines. The main reason for having a call stack is so that the program can keep track of where a subroutine should return control to once it finishes executing.
A stack frame is a part of the call stack, and a new stack frame is created every time a subroutine is called. So, in our recursive factorial() method above, a new stack frame is created every time the method is called. The stack frame is used to store all of the variables for one invocation of a routine. So, remember that a call stack is basically a stack of stack frames.
Let's divide the process into 4 parts, since the number chosen is 4.
1st Iteration
static int factorial(4){
if (4 == 1){
return 1;
}
return 4 * factorial(3);
}
2nd Iteration
static int factorial(3){
if (3 == 1){
return 1;
}
return 3 * factorial(2);
}
3rd Iteration
static int factorial(2){
if (2 == 1){
return 1;
}
return 2 * factorial(1);
}
4th Iteration
static int factorial(1){
if (1 == 1){
return 1;
}
return 2 * factorial(number-1);
}
You can see that the first stack frame is created with a number equal to 4.
Then a call to factorial(3) is made – so the first call to factorial(4) does not run to completion because another call (factorial(3)) is made before the very first call to factorial can run to completion.
Same is the case for others.
A stack frame is used to hold the state of the first call to factorial(). It stores the local function variables (and their values) of the current invocation of factorial(), and it will also store the return address of the method that called it (since we are talking about the very first non-recursive invocation of factorial(), whatever routine invoked factorial() in the first place is where Factorial would return when it is completely done with everything).
Because the stack frame also stores the return address, the factorial() function knows where to return to when it finishes running
Process Execution
Finally, in the 4th stack frame, we run into our base case, which
means the recursive calls are finished and then control is returned to
the 3rd stack frame, where factorial(1) * 2 is calculated to be
2, and then control is returned to the 2nd stack frame where factorial(2) * 3 is calculated to be 6, and then control is
returned to the 1st stack frame where factorial(3) * 4 is
calculated to be 24. Finally, our result of 24 is returned.
My understanding about return statement in a function was, After return the function is over.
But it's wrong as i tried to understand the flow of a recursive function:
public class Recursions {
int recursions(int i){
if(i==1){
System.out.println(i);
return 1;
}
else{
int j=(i*recursions(i-1));
System.out.println(j);
return j;
}
}
public static void main(String[] args) {
Recursions r=new Recursions();
r.recursions(4);
}
}
The output is:
1
2
6
24
But according to my understanding it should be: 1
I failed to understand the output as it suggests in case of recursion after return statement the pointer goes to the previous call? Thanks in Advance
It is important to distinguish between a method (the thing you have in your source code), and the method invocation (one execution of that method at runtime). The return statement ends the current method invocation.
That is, a method invocation expression (such as recursions(i-1)) is evaluated by
set aside a little memory to hold the data for this method invocation (such as the values of the method paramaters and local variables). For the technically minded, this region of memory is called the stack frame, and is part of the the current thread's stack)
evaluate the argument expressions, and assign their values to the method parameters
execute the body of the method (until we either reach the end of the method body, or a return statement. In the latter case, keep the return value somewhere)
free the memory set aside for the method invocation
the value of the method invocation expression is the return value computed in step 3
So whenever execution reaches a method invocation expression, a new method invocation begins. Once that method invocation has terminated, execution of the original method invocation is resumed.
Your program will therefore be executed as follows:
begin invocation of recursive with i = 4
begin invocation of recursive with i = 3
begin invocation of recursive with i = 2
begin invocation of recursive with i = 1
print 1
return 1
invocation ends with return value 1
j = 2 * 1
print j
return j
invocation ends with return value 2
j = 3 * 2
print j
return j
invocation ends with return value 6
j = 4 * 6
print j
return j
invocation ends with return value 24
There is nothing strange about this behavior, this is how recursion always works. If you add a println statement before the first if:
int recursions(int i) {
System.out.println("------> calling recursions(" + i + ")");
if (i == 1) {
You get this output:
------> calling recursions(4)
------> calling recursions(3)
------> calling recursions(2)
------> calling recursions(1)
1
2
6
24
So when you call recursions(4) in main() you get to the else (as i is 4). So we get:
i * recursions(4-1)
This goes into recursions(3) which gets to i (now equal to 3) * recursions(2).
This in turn gets you into recursions(2) and i (now 2) * recursions(1).
recursion(1) finally returns 1 and the values are all propagated up the stack with the returns from the previous recursions calls. In each case, just before the return statement, you are printing the current i times the result of the previous recursions call.
Everytime you call a function,it creates another frame in the stack,
F1, F2,F3,F4,
when return is called for example in F4, F4 will be finished, but still others will remain. And F3 will use the return value and it'll return another value too.. it goes like that for each function.
After return the function is over
No.
After the return, that particular function call is over. The return only returns from the current call to the method. It returns to the caller, which in this case is typically another call to the same method.
But according to my understanding it should be: 1 I failed to understand the output as it suggests in case of recursion after return statement the pointer goes to the previous call?
That's exactly what happens. The "previous" call is the outer call to recursions.
And that is what is supposed to happen. Not just in Java. In any programming language that supports recursive method/function/procedure/subroutine calls.
Code:
public static void main(String[] args) {
System.out.println(test(13549));
}
public static int test(int a){
if(a<10)
return a;
int b = (a%10);
int c = test(a/10);
int d = Math.max(b,c);
return d;
}
I understand what the method does (after using the debugger) and I understand that the method calls itself till it is less than 10 and it runs and checks what's bigger, b or c.
Now what I don't understand is that why when there is the return statement return d; it returns to int c = test(a/10) and not to the start of the method of int test(int a){.
The return statement returns the output of the call to test. So on the line return d; it's just returning the value of test(a/10) in the line c = test(a/10).
This is a basic idea of recursion - when you call the method within itself, it isn't just jumping back to the start of the method.
visually:
1
|
| 2
|__|
| | 3
| |__|
| | x
| |__|
| .
| .
Where each vertical line the running of the function, and the horizontal lines are recursive calls.
After each call, it returns back to the place in the instance of the method it was called in
Effectively, that means that in the 3rd recursion, you have 3 versions of the function on the stack (in memory), rather than simply going back to the top of the current function 3 times.
When tracing your code, imagine you have a stack (of function execution). Whenever you find the function is calling itself, put a new function execution on top of the stack, and when the function returns take out the stack element.
You'll find that the function will keep calling itself until it reach the 'base case' -- when a<10.
Putting a code below a return statement won't do any good (in some language it won't even compile), none of the code will get executed once the function returns
Each time you call your recursive function, it starts from the top of the function. Since you have d defined after your recursive function call you will never get to d. You will continue to recursively call your function until you are able to return a.
When you call test(13549) this is what happens:
test(13549){
false
b=9
c= test(1354){
false
b=4
c=test(135){
false
b=5
c=test(13){
false
b=3
c=test(1){
true
return 1
}
d=Max(3,1)
return 3
}
d=Max(3,3)
return 3
}
d=Max(5,3)
return 5
}
d=Max(4,5)
return 5
}
d=Max(9,5)
return 9
}
Sorry if I may have miscalculated in any way.. but there you can see, that the first return statement is not reached until all recursive calls are finished and the very first c hast an actual value.