0

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

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();
  }
}

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.

aeter
  • 11,960
  • 6
  • 27
  • 29
  • 1
    As a side note, this is pretty terrible code. You'll never see anything like this in the production world. It's hideous. – San Jacinto Aug 21 '09 at 19:01
  • Still, I think it's pretty educational to see how it works. – Imagist Aug 21 '09 at 19:21
  • @imagist yeah, i'll go with that. it's good to bend minds when they start out into this stuff. it's more that some developers never learn to avoid this type of programming, having the "if it compiles and runs, it's fine!!" attitude, never payying any mind to how complex the code is to debug and maintain over time. – San Jacinto Aug 21 '09 at 19:26
  • Does this answer your question? [Is there any way to do n-level nested loops in Java?](https://stackoverflow.com/questions/426878/is-there-any-way-to-do-n-level-nested-loops-in-java) – Ilya Lysenko Mar 03 '20 at 00:11

2 Answers2

3

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
  • 8,774
  • 5
  • 43
  • 58
  • 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 Aug 21 '09 at 19:11
  • +1 for the "hideous" comment. It even took me a second to see what was going on here. – GRB Aug 21 '09 at 19:12
  • @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 Aug 21 '09 at 19:15
  • @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 Aug 22 '09 at 05:23
  • @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 Aug 22 '09 at 06:13
0

It might be solved with this library, for example.

In your case you can implement loops so:

new Loops()
    .from(1).to(4)
    .from(1).to(4)
    .action(System.out::println);

The result:

[1, 1]
[1, 2]
[1, 3]
[2, 1]
[2, 2]
[2, 3]
[3, 1]
[3, 2]
[3, 3]
Ilya Lysenko
  • 1,772
  • 15
  • 24