how to write n-level embeded loop with java

前端 未结 3 546
情书的邮戳
情书的邮戳 2020-12-22 12:22

Given M integers (N1, N2, Nm), I want to write a N-level embedded loop like following :

for (int a = 0; a < N1; a++)
  for (int b = 0; b < N2; b++)
           


        
相关标签:
3条回答
  • 2020-12-22 12:54

    No need for recursion. Instead, think of each iterator as a digit in a number. When you increment the number, you increment the last digit, and if it exceeds the limit (normally 10), it's set to 0, and the digit to the left of it is increased, repeating the overflow logic.

    In this case, each "digit" is an independent counter, each with their own "limit", i.e. the value of the given Nx. If you store those limit values in an array, and keep the counters in a same-size array, the logic is fairly simple.

    Here is an example of an optimized version, that uses a label to exit directly from a nested loop:

    int[] n = { 3, 4, 5 }; // m = 3: N1 = 3, N2 = 4, N3 = 5
    
    int[] i = new int[n.length]; // All "digits" are 0
    LOOP: for (;;) {
        // operation using i[] here, e.g.
        System.out.println(Arrays.toString(i));
    
        // Process "digits" from last to first
        for (int j = i.length - 1; ; j--) {
            if (j < 0) // Exit main loop if first "digit" overflowed
                break LOOP;
            if (++i[j] < n[j]) // Increment "digit", and if not overflowed:
                break;         //   exit digit-loop, i.e. loop back to process
            i[j] = 0; // Reset "digit" to 0, then process next (to left) "digit"
        }
    }
    

    Output

    [0, 0, 0]
    [0, 0, 1]
    [0, 0, 2]
    [0, 0, 3]
    [0, 0, 4]
    [0, 1, 0]
    [0, 1, 1]
    [0, 1, 2]
    [0, 1, 3]
    [0, 1, 4]
    [0, 2, 0]
    [0, 2, 1]
    [0, 2, 2]
    [0, 2, 3]
    [0, 2, 4]
    [0, 3, 0]
    [0, 3, 1]
    [0, 3, 2]
    [0, 3, 3]
    [0, 3, 4]
    [1, 0, 0]
    [1, 0, 1]
    [1, 0, 2]
    [1, 0, 3]
    [1, 0, 4]
    [1, 1, 0]
    [1, 1, 1]
    [1, 1, 2]
    [1, 1, 3]
    [1, 1, 4]
    [1, 2, 0]
    [1, 2, 1]
    [1, 2, 2]
    [1, 2, 3]
    [1, 2, 4]
    [1, 3, 0]
    [1, 3, 1]
    [1, 3, 2]
    [1, 3, 3]
    [1, 3, 4]
    [2, 0, 0]
    [2, 0, 1]
    [2, 0, 2]
    [2, 0, 3]
    [2, 0, 4]
    [2, 1, 0]
    [2, 1, 1]
    [2, 1, 2]
    [2, 1, 3]
    [2, 1, 4]
    [2, 2, 0]
    [2, 2, 1]
    [2, 2, 2]
    [2, 2, 3]
    [2, 2, 4]
    [2, 3, 0]
    [2, 3, 1]
    [2, 3, 2]
    [2, 3, 3]
    [2, 3, 4]
    
    0 讨论(0)
  • 2020-12-22 12:55

    How about using recursive:

    int recursive_loop(int var_M){
        if(var_M == destination) return 0;
        else{
            for(int i=0;i<var_M || recursive_loop(var_M+1) ; i++){
                // Do operation here
            }
        }
    }
    

    I tested with C , it work.

    0 讨论(0)
  • 2020-12-22 13:06

    The same solution as @Andreeas', just with more explanations (he was faster in posting the answer, I'm adding mine to give myself a reason for the time I spent with the explanations):

    import java.util.Arrays;
    
    public class Multiloop {
    
      static public void doSomething(int... maxIndexes) {
        // quick check: if any of the maxIndexes is zeo or less
        // there's a snowball in a furnace chance for the most inner loop
        // to get executed
        for(int i=0; i<maxIndexes.length; i++) {
          if(maxIndexes[i]<=0) {
            return; // nothing to do
          }
        }
        // java guarantees all of then are zero after allocation
        int multiIndex[]=new int[maxIndexes.length];
    
        int currIndexPos=maxIndexes.length-1; // start looping with the last
        do {
          // this happens when the current index reached its correspondent maximum
          // which of course is maxIndexes[currIndexPos]-1
          while(
              currIndexPos>=0 && 
              multiIndex[currIndexPos]>=maxIndexes[currIndexPos]-1
          ) {
            currIndexPos--; // search for the prev one to increment
          }
          if(currIndexPos<0) {
            // all the indexes have reached their max  value, we are done
            break;
          }
          // if it's not the last index, we need to increment the current one
          // and reset to zero all the others following it 
          if(currIndexPos<maxIndexes.length-1) {
            // if not at the max value, then it's safe to increment it
            multiIndex[currIndexPos]++;
            Arrays.fill(multiIndex, currIndexPos+1, maxIndexes.length, 0);
          }
          // and now all multicycle indexes are to their proper value
          // we reset the currIndexPos to the max and the do what we need to do
          currIndexPos=maxIndexes.length-1;
    
          /// Cut along the dotted lines and place your own code
          /// ✂...✂...✂...✂...✂...✂...✂...✂...✂...✂
          { // the inner-most cycle, using the multicycle indexes as necessary
            // replace it with what you need here
            // **** Just don't screw up the currIndexPos!!! 
            // **** unless you know what you are doing 
            // **** (e.g. breaking any of the "cycles" on the way)
            char nameForIndex='a';
            for(int i=0; i<maxIndexes.length; i++) {
              if(i>0) {
                System.out.print(',');
              }
              System.out.print(nameForIndex+"="+multiIndex[i]);
              nameForIndex++;
            }
            System.out.println();
          }
          // ✂...✂...✂...✂...✂...✂...✂...✂...✂...
    
          multiIndex[currIndexPos]++;
        } while(true); // the exit condition is handled at the cycle start anyway
      }
    
    
      static public void main(String args[]) {
        // a triple cycle with their respective max indexes
        doSomething(2,4,3);
      }
    }
    

    Output:

    a=0,b=0,c=0
    a=0,b=0,c=1
    a=0,b=0,c=2
    a=0,b=1,c=0
    a=0,b=1,c=1
    a=0,b=1,c=2
    a=0,b=2,c=0
    a=0,b=2,c=1
    a=0,b=2,c=2
    a=0,b=3,c=0
    a=0,b=3,c=1
    a=0,b=3,c=2
    a=1,b=0,c=0
    a=1,b=0,c=1
    a=1,b=0,c=2
    a=1,b=1,c=0
    a=1,b=1,c=1
    a=1,b=1,c=2
    a=1,b=2,c=0
    a=1,b=2,c=1
    a=1,b=2,c=2
    a=1,b=3,c=0
    a=1,b=3,c=1
    a=1,b=3,c=2
    
    0 讨论(0)
提交回复
热议问题