views:

209

answers:

1

In a beginner's programming book (free licence) there was the following code, dynamically creating nested loops in Java:

import java.util.Scanner;

public class RecursiveNestedLoops {
  public static int numberOfLoops;
  public static int numberOfIterations;
  public static int[] loops;

  public static void main(String[] args) {
     Scanner input = new Scanner(System.in);
     System.out.print("N = ");
     numberOfLoops = input.nextInt();
     System.out.print("K = ");
     numberOfIterations = input.nextInt();
     input.close();
     loops = new int[numberOfLoops];
     nestedLoops(0);
  }

  public static void nestedLoops(int currentLoop) {
     if (currentLoop == numberOfLoops) {
       printLoops();
       return;
     }
     for (int counter=1;counter <= numberOfIterations;counter++) {
       loops[currentLoop] = counter;
       nestedLoops(currentLoop + 1);
     }
  }

  public static void printLoops() {
     for (int i = 0; i < numberOfLoops; i++) {
       System.out.printf("%d ", loops[i]);
     }
     System.out.println();
  }
}

i

When inputting N=2 and K=3, on the screen should be printed something like [1,1],[1,2],[1,3],[2,1],[2,2],[2,3],[3,1],[3,2],[3,3] (with newlines, etc). The program works fine. Then I tried to debug it and spent a quite some time trying to understand how exactly it works. I couldn't. My question:

----> why after printing [1,3] the variable 'curentLoop' becomes '0' being beforehand '1' ?

Also: -> In my debugger (Eclipse built-in) after printing [1,3] the pointer goes to the end '}' brace of the method 'nestedLoops' (with 'currentLoop' with value 1), and then suddenly it starts executing the for-loop with 'currentLoop' = 0. Where does the variable take its value '0' from? Why after going to the end brace of the method, it starts executing the 'for loop', without any call to the method's name?

This could be a very easy question to some of you; I'm just a beginner. Thank you in advance for your help.

+3  A: 

Because it's a recursive call to nested loops. first, it is called with 0. then it is called with 1. then with 2. when it gets to the number of total loops, it begins executing the loops (this is called the recursive terminal condition). however, each call to nested loops is placed on the stack, it executes k, then returns and executes k-1, then returns and executes k-2, then returns and executes k-3 all the way down to k - k = 0.

if i were you, i would place a breakpoint on the call of nestedloops() inside itself and watch what it is being called with. then, as it is called, watch it work its way back down.

San Jacinto
So you mean the line 'nestedLoops(currentLoop + 1);' creates a stack of 3 methods 'nestedLoops(int currentLoop)', each one of them containing a 'for' loop, did I get it right?
aeter
+1 for the "hideous" comment. It even took me a second to see what was going on here.
GRB
@aeter more or less. nestedloops is called with zero like so: nestedloops(0). then, it calls itself over and over, incrementing the argument passed in until the max k (number of loops) is reached.. please look at it in your debugger to get a picture of what is going on.
San Jacinto
Thank you very much, now I understood it. Thank you for your great explanation.
aeter
@aeter: I'd bet money that this example is in an section of your book that is introducing the concept of *recursion*. This is an example of recursion: where a procedure ends up calling itself.
Stephen C
@Stephen C: yes, you are right. Also the question is tagged with 'recursion'. Though particularly in this code, the program flow was (very) hard for me to understand before asking here.
aeter