Understanding Java recursion with the Eclipse debugger

I am looking through some simple recursion exercises in Java to understand the concept (which I am struggling with). For all of my research up to this point, I have relied heavily on the Eclipse debugger to understand exactly what my code is doing. However, when it comes to recursion, I believe that this is not so, because it is difficult to accurately track what is happening.

Given the following code, a method that returns the n th Fibonacci number:

 public int fibonacci(int n) { if (n == 0 || n == 1) { return n; } else { return fibonacci(n - 1) + fibonacci(n - 2); } } 

When using a debugger for this code, it’s quite difficult to accurately track what is happening and where / when. Having only one variable, it changes every step, and with a small value of n , such as 7, it is already difficult to track because there are so many steps that are completed before 13.

I would like to know:

  • How can I better debug recursion code (in general) in order to better understand recursion?
  • I focus too much on debugging for this kind of thing, given the concept of return fibonacci(n - 1) + fibonacci(n - 2) , which is easy to understand?
+5
source share
4 answers

You can debug it with a simple System.out.prinln() in each instruction where you print the value of n and its value of fibonnacci .

Here is a sample 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 DEMO here .

+1
source

How to debug recursion code?

First, make sure you switch to the "Debugging" perspective, and you see the correct windows ( Variables , Expressions , Debug and your source code), for example. eg:

Eclipse - debug recursion

Then notice that in Debug you can see how often the method is being called. This list will grow and shrink depending on how many methods have been called and have not yet returned.

You can click one of the methods to change the scope. See how the contents of Variables change as the region changes.

Finally, to test arbitrary things, enter expressions in the Expressions window. It is almost like live coding. You can check almost everything.

Am I focusing too much on debugging?

Not. Learn to do it right, and it will save you a lot of time later.

Adding System.out.println() needs to be recompiled, and you need to reproduce a situation that is not always so simple.

+3
source

The "built-in" code complicates the use of the Eclipse debugger because it focuses heavily on showing local variables that are not there. You can make it simpler by making things more verbose and storing variables. This way you can more easily see what is happening and what are the results. For example, modifying the code as follows will facilitate the use of the debugger:

 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 tried to compile this code.

+1
source

It took me a while to figure out recursion, and for one reason or another, I never found the debuggers useful. I will try to explain to you how I do it, and this is not related to the debugger ( disclaimer : this is a personal method, and it may be wrong or not common).

  • In recursive code, you always have at least a completion block and a recursive block. Mentally isolate these 2 sections.

    return n; β†’ completion block

    return fibonacci(n - 1) + fibonacci(n - 2); β†’ recursion block

  • The recursion block expresses the abstract recursion rule (s). Instead of these values ​​in the variables Fn1 and Fn2 you get these values ​​using the same function. Think of a brick wall: your recursive function creates a wall that adds brick to an existing wall. Inside the recursion block, at a certain stage, you don’t mind who and how the created wall was created, you just add a new brick to it. This happens when the wall was created by the same function, one brick at a time.

  • In the completion block, the code is called with some values. What should happen at the end of the process before this value? Speaking of Fibonacci, at the end of the process ( n = 1 or n = 0 ) I have to add this number to the total again. This is done using a recursive block. In other words, the completion block provides concrete values ​​(and not the process of obtaining them) to the recursion block.

When I need to troubleshoot, I print the values ​​at every step, and this is the best solution I have found for me. Then I check that they are what they should be. For your Fibonacci, I would like to see a conclusion similar to

the 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; } } 

Conclusion:

 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 Induction information that is strictly related to recursion.

0
source

All Articles