I'm starting learning Java. I have a task to make a recursion function. I was looking for information about recursion in Java and found some interesting code. I can't understand, when n equals 10, why n after "return" n equals 9. And then, when k equals 9, after "return" k = 10.
public class lvl22666 {
public static void main(String[] args) {
recTest(0,10);
}
static void recTest(int n, int k) {
if (n == k) {
return;
} else {
if (n < k) {
n++;
System.out.println(n + " " + k);
recTest (n,k);
}
if (k > n) {
k--;
System.out.println(n + " " + k);
recTest (n,k);
}
}
}
}
All recursive methods have three things:
An exit condition, to prevent an endless loop
A work item, and
A recursive call.
The exit condition in your recursive function is:
if (n == k)
return;
The work item is:
n++;
System.out.println(n + " " + k);
Unless k is greater than n, in which case the work item is:
k--;
System.out.println(n + " " + k);
The recursive call is:
recTest (n,k);
Note that, since a return early-exits you out of the method, the else statement is not required.
To understand the behavior of a recursive method, you must first understand what a stack frame is, how the stack works, and how it serves to preserve state between method calls.
When Java prepares to call a method, it puts the calling methods' local variables including its parameters (collectively, the method's "state") and the return address of the calling method into a stack frame, and pushes that stack frame onto the stack. It then calls the new method.
When Java returns from a method, it pops the stack frame off the stack, restoring the calling method's original state.
A stack is like the stack of plates you see in the carousel at a 50's diner; the first plate off the stack is the last plate the dish washer put there. We call this a last-in, first-out (LIFO) queue.
With a little imagination, you can see how successive calls to a recursive method will keep a running history of any changes made to the state during each recursion. Since a copy of the state is saved during each recursion, you can walk back to a previous step in the state by returning from a method call.
What this function does is iterate through it, until n equals k.
if (n == k) {
return;
This checks if n equals k and returns to the main function, if this is true.
If not, it checks which of the two numbers is smaller and adds it by one.
After doing that, the function calls itself with the new values of n and k and the whole function repeats. As stated earlier, this is done until n is equal to k which triggers a return. This exits the function and jumps to the next line of code (after recTest(0,10);).
If you have any further questions don't be afraid to ask!
Related
I'm learning recursion now, and I thought I quite understood how recursion works, and then I saw this code, and my head is about to explode.
I know this simple recursion works like
public void recursivePrint(int number){
if(number == 0{
return;
}
System.out.println(number + " ");
recursivePrint(number - 1);
}
If the parameter "number"'s value is 2.
public void recursivePrint(2){
if(number == 0{
return;
}
System.out.print(2 + " ");
recursivePrint(2 - 1);
}
public void recursivePrint(1){
if(number == 0{
return;
}
System.out.print(1 + " ");
recursivePrint(1 - 1);
}
and then stops because it meets its base case.
What about this print all permutations of a string function?
private void permute(String str, int l, int r)
{
if (l == r)
System.out.println(str);
else
{
for (int i = l; i <= r; i++)
{
str = swap(str,l,i);
permute(str, l+1, r);
str = swap(str,l,i);
}
}
}
There is a recursive call inside a for loop. If the input value is "ab", how does this recursion function work? Can you explain as I wrote above?
I got this code form geeksforgeeks, and there's a video for this, but I can't understand this since I don't know how loop works in recursion.
Using permute function you are generating strings where lth char is being replaced by one of the char following it. With the for loop inside it, you are touching onto each of those following characters one at a time.
With several call to permute, you are able to advance till the end position of the string, and that end is checked by if (l == r)
Take the case of abc.
abc
/ | \
Level 1 a(bc) b(ac) c(ba) (Here three new call to permute are made out of permute with l=1)
Goes on...
FYI, permutation isn't that simple to understand if you are new to recursion or programming. For easy understanding use pen-paper.
Recursion occurs when a method calls itself. Such a method is called recursive. A recursive method may be more concise than an equivalent non-recursive approach. However, for deep recursion, sometimes an iterative solution can consume less of a thread's finite stack space.
What is recursion:
In general, recursion is when a function invokes itself, either directly or indirectly. For example:
// This method calls itself "infinitely"
public void useless() {
useless(); // method calls itself (directly)
}
Conditions for applying recursion to a problem:
There are two preconditions for using recursive functions to solving a specific problem:
There must be a base condition for the problem, which will be the endpoint for the recursion. When a
recursive function reaches the base condition, it makes no further (deeper) recursive calls.
Each level of recursion should be attempting a smaller problem. The recursive function thus divides the problem into smaller and smaller parts. Assuming that the problem is finite, this will ensure that the recursion terminates.
In Java there is a third precondition: it should not be necessary to recurse too deeply to solve the problem;
The following function calculates factorials using recursion. Notice how the method factorial calls itself within the function. Each time it calls itself, it reduces the parameter n by 1. When n reaches 1 (the base condition) the function will recurse no deeper.
public int factorial(int n) {
if (n <= 1) { // the base condition
return 1;
} else {
return n * factorial(n - 1);
}
}
So, I am currently creating a method for an assignment using recursion. I need to take an int, then print going down until it hits 0. After that, I need to print going up until it hits the original number, then stopping. Here's my code so far.
public static void recursivePrinter(int levels)
{
final int start = levels;
if (levels < start ) {
System.out.println("Going up! " + levels);
recursivePrinter(levels + 1);
}
else {
System.out.println("Going down! " + levels);
recursivePrinter(levels - 1);
}
return;
}
You don't reach the return; statement. the code always go in the else statement. to keep track of the starting number you could use a global variable . also you need to add a condition where the recursion should finish. so you can try some thing like this :
static int start = 10;
public static void recursivePrinter(int levels)
{
if (levels < start ) {
System.out.println("Going up! " + levels);
recursivePrinter(levels + 1);
}
else {
System.out.println("Going down! " + levels);
// recursivePrinter(levels - 1);
start-- ;
}
return;
}
In an attempt to provide a meaningful answer to help future visitors (as opposed to the comment thread on the question above)...
The initial problem was two-fold:
The method had no condition in which it doesn't recursively call itself. Which results in an infinite recursion. There must always be some condition by which the method stops recursion.
The method was locally storing a value that it doesn't need, and the logic was incorrectly assuming that value won't be different for each call to the method.
Essentially, a recursive method almost always follows a basic structure:
method(argument) {
terminating condition;
state change or method action;
recursive call;
}
Depending on the state change or the method action, this can be a bit more complex. But the basic components are generally always there in one form or another.
In your case, the argument is an integer, the terminating condition is testing whether that integer is a known value, the state change is changing the integer, the method action is printing the integer, and the recursive call is invoking the method with the new integer.
Based on your comment above:
It's supposed to count down from 3 (3, 2, 1) and then back up to 3 (1, 2, 3).
Consider the following pseudo-code (so as to not do your homework for you) structure:
myMethod(level) {
// terminating condition
if level is 0
return
// method action
print level
// recurse
myMethod(level - 1)
}
This would be a great time to step through the code in your debugger and see what a recursive method call actually does. Each time the method is invoked, it's an isolated action unaware of any other invocations of the method. It's "building a stack" of calls to itself. When the terminating condition is reached, that stack will "unwind" and those calls will all return to each other in reverse order.
Given this, printing the numbers "counting back up" is a natural result of just printing it again in the method:
myMethod(level) {
// terminating condition
if level is 0
return
// method action
print level
// recurse
myMethod(level - 1)
// more method action
print level
}
That last operation simply prints the value a second time. But it does so after the recursive call, therefore after all printing of lower numbers done within that recursive call, regardless of how many there are.
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.
I was trying to implement the coin change problem using recursion. I have written the following code and am facing a problem with the static class variable. 'answer' is a class variable and i am trying to add the return value to it in the loop. This works fine within the while loop but after the while loop ends the answer is reset to 0;
while (i * currentCoin <= sum) {
System.out.println("inside while; answer is " + answer);
answer = answer
+ findCombinations(
sum - i * currentCoin,
new ArrayList<Integer>(denominations.subList(1,
denominations.size())));
i++;
}
Below is all the code that I have written. You can copy and run it to check.
import java.util.ArrayList;
import java.util.Collections;
public class CoinChangeHashMap {
static int answer = 0;
public static void main(String[] args) {
int[] array = new int[] { 7, 3, 2 };
ArrayList<Integer> input = new ArrayList<Integer>();
getList(array, input);
findCombinations(12, input);
System.out.println(answer);
}
private static void getList(int[] array, ArrayList<Integer> input) {
for (int i : array) {
input.add(i);
}
}
public static int findCombinations(int sum, ArrayList<Integer> denominations) {
if (denominations.size() == 1) {
if (sum % denominations.get(0) == 0) {
return 1;
}
return 0;
}
int i = 0;
int currentCoin = denominations.get(0);
while (i * currentCoin <= sum) {
System.out.println("inside while; answer is " + answer);
answer = answer
+ findCombinations(
sum - i * currentCoin,
new ArrayList<Integer>(denominations.subList(1,
denominations.size())));
i++;
}
return 0;
}}
**The output that I get is 0. but the expected output is 4. While debugging the output that I got is **
inside while; answer is 0
inside while; answer is 0
inside while; answer is 1
inside while; answer is 1
inside while; answer is 2
inside while; answer is 2
inside while; answer is 0
inside while; answer is 0
inside while; answer is 0
0
Any Help is appreciated.
The problem is related to your odd code structure, in which you convey the outcome of your recursive call sometimes by modifying static variable answer, and sometimes via the method's return value.
If you analyzed the problem more closely, you would discover that it is not upon exit from the loop that the partial results are lost, but rather some time after return from the method. Therefore, consider carefully the way you update the answer:
answer = answer + findCombinations( /* ... */ );
At the top-most level of your recursion, answer is initially 0. When Java evaluates the above expression, it evaluates first the left operand and then the right operand, then it adds them. That is, it evaluates answer, getting the result 0, before it performs the recursive call. The value of answer may be updated in the course of the recursive call, but those changes come too late. Only the bottom-most level of the recursion ever returns a value different from zero, so if the recursive call itself recurses at least one level deeper then it will return zero. In that case, the sum is computed as 0 + 0, and assigned to answer, clobbering any update the method performed.
You could resolve the problem by swapping the order of the operands in your sum, but it would be better, and not much harder, to get rid of the static variable altogether. Use a local variable within the method to accumulate results, and in all cases convey the total back to the caller via the method's return value.
I am going through some simple recursion exercises in Java in order to understand the concept (which I struggle with). For all my study up to this point, I have relied heavily on Eclipse's debugger in order to understand exactly what my code is doing. However, when it comes to recursion, I find this not to be the case, because it is difficult to track exactly what is happening.
Considering the following code, a method that returns the nth Fibonacci number:
public int fibonacci(int n) {
if (n == 0 || n == 1) {
return n;
} else {
return fibonacci(n - 1) + fibonacci(n - 2);
}
}
When using the debugger for this code, it's pretty difficult to track exactly what is happening and where/when. With only one variable, it changes every step, and, with a small n value, such as 7, it is already becoming difficult to track, due to the fact that there are so many steps that are executed before 13 is eventually reached.
I would like to know:
How can I debug my recursion code (in general) in a better way, in order to better understand recursion?
Am I focussing too much on debugging for this sort of thing, considering the concept return fibonacci(n - 1) + fibonacci(n - 2) is simple to understand?
How can I debug my recursion code?
First, make sure you have switched to the Debug perspective and you're seeing the correct windows (Variables, Expressions, Debug and your source code) e.g. like this:
Next, note that in Debug you can see how often the method is currently called. This list will grow and shrink depending on how many methods were called and have not returned yet.
You can click on one of the methods to change the scope. See how the contents of Variables changes when you change the scope.
Finally, to check arbitrary things, enter expressions in the Expressions window. This is almost like live coding. You can inspect virtually anything.
Am I focussing too much on debugging?
No. Learn doing it right and it will save you much time later.
Adding a System.out.println() needs to recompile and you need to reproduce the situation which is not always that simple.
You can debug it using a simple System.out.prinln() in each instruction where you print n value and its fibonnacci value.
Here's an example code:
public int fibonacci(int n) {
if (n == 0 || n == 1) {
System.out.println("your value is: " +n+ " and its Fibonacci value is: "+n);
return n;
} else {
System.out.println("your value is: " +n+ " and its Fibonacci value is: "+fibonacci(n - 1) + fibonacci(n - 2));
return fibonacci(n - 1) + fibonacci(n - 2);
}
}
You can test the DEMO here.
"Inline" code makes it more difficult to use the Eclipse debugger because it has a strong focus on showing local variables which are not present. You can make this easier to step through by making things more verbose and saving to variables. This way you can more easily see what is happening and what results are. For example, modifying your code as follows will make it easier to use the debugger on:
public int fibonacci(int n) {
if (n == 0 || n == 1) {
return n;
} else {
int nMinus1 = fibonacci(n - 1);
int nMinus2 = fibonacci(n - 2);
int retValue = nMinus1 + nMinus2;
return retValue;
}
}
DISCLAIMER: I have not attempted to compile this code.
It took me a while to grasp recursion and, for one reason or another, I never found the debuggers useful. I'll try to explain you how I do and it doesn't involve the debugger (disclaimer: this is a personal method and it might by incorrect or not general).
In recursive code you always have at least a termination block and a
recursion block. Isolate mentally these 2 sections.
return n; -> termination block
return fibonacci(n - 1) + fibonacci(n - 2); -> recursion block
The recursion block express the abstract rule(s) of recursion. Instead of having those values in variables Fn1 and Fn2, you obtain these values using the same function. Think about a brick wall: your recursive function creates the wall adding a brick to an existing wall. Inside the recursion block, at a certain step, you don't mind who and how the existing wall has been created, you simply add to it a new brick. It happens then that the wall has been created by the same function, one brick at the time.
At the termination block the code is called with some values. What should happen at the end of the process to that value? Speaking about Fibonacci, at the end of the process (n = 1 or n = 0) I have to again add these number to the total. This is done by the recursive block. In other words the termination block gives the concrete values (and not a process on how to obtain them) to the recursion block.
When I have to troubleshoot I print the values at every step, and this is the best solution I've found for me. Then I check that they are what they are supposed to be. For your Fibonacci, I would like to see an output like
Code:
public static int fibonacci( int n ) {
System.out.println( "\nInput value: " + n );
if( n == 0 || n == 1 ) {
System.out.println( "Terminating block value: " + n );
return n;
}
else {
System.out.println( "Recursion block value: fibonacci(" + (n - 1) + ") + fibonacci(" + (n - 2) + ")" );
int result = fibonacci( n - 1 ) + fibonacci( n - 2 );
System.out.println( "Recursion block return value: " + result );
return result;
}
}
Output:
Input value: 4
Recursion block value: fibonacci(3) + fibonacci(2)
Input value: 3
Recursion block value: fibonacci(2) + fibonacci(1)
Input value: 2
Recursion block value: fibonacci(1) + fibonacci(0)
Input value: 1
Terminating block value: 1
Input value: 0
Terminating block value: 0
Recursion block return value: 1
Input value: 1
Terminating block value: 1
Recursion block return value: 2
Input value: 2
Recursion block value: fibonacci(1) + fibonacci(0)
Input value: 1
Terminating block value: 1
Input value: 0
Terminating block value: 0
Recursion block return value: 1
Recursion block return value: 3
You can also find useful to read about Induction, which is strictly related to recursion.