2013-10-16 61 views
15

我有必須執行以下操作的方法:如何使n個嵌套for循環遞歸?

for (int a01 = 1; a01 <= 25; a01++) { 
    for (int a02 = a01 + 1; a02 <= 25; a02++) { 
     for (int a03 = a02 + 1; a03 <= 25; a03++) { 
      ... 
      System.out.println(a01 + "," + a02 + "," + ... + "," + a015); 
     } 
    } 
} 

我想指定的嵌套對的數量(在上述情況下,我想15嵌套了的)。 有沒有辦法在這裏使用遞歸編程?

+14

請不要。不要這樣做。 –

+4

只需創建一個方法並讓它自己調用15次。這是一個真正的遞歸方法。 – BalusC

+1

@SotiriosDelimanolis謹慎解釋爲什麼? ;-) –

回答

15

是的。這可以通過遞歸編程來執行。

我假設你不喜歡把這些嵌套的代碼寫在源代碼中 - 就像在你的例子中那樣,因爲這是非常醜陋的編程 - 就像評論員解釋的那樣。

以下(僞Java樣)代碼說明了它。我假設嵌套的深度是固定的。然後,您實際上喜歡遍歷維度深度的整數向量。

int[] length = new int[depth]; 
int[] counters = new int[depth]; 

陣列counters必須被初始化爲0(Arrays.fill(counters,0))。必須將數組length初始化爲相應for循環的迭代次數。

我假設你喜歡在內循環內執行某個操作。我會稱之爲 performOperation(int[] counters); - 它取決於多維計數器,即外部計數器的計數器。

然後你就可以通過調用

nestedLoopOperation(counters, length, 0); 

其中

void nestedLoopOperation(int[] counters, int[] length, int level) { 
    if(level == counters.length) performOperation(counters); 
    else { 
     for (counters[level] = 0; counters[level] < length[level]; counters[level]++) { 
      nestedLoopOperation(counters, length, level + 1); 
     } 
    } 
} 

在你的情況下運行嵌套的for循環您的System.out.println()將

performOperation(int[] counters) { 
    String counterAsString = ""; 
    for (int level = 0; level < counters.length; level++) { 
     counterAsString = counterAsString + counters[level]; 
     if (level < counters.length - 1) counterAsString = counterAsString + ","; 
    } 
    System.out.println(counterAsString); 
} 
+0

你的內部函數調用缺少一個參數「length」。 – Teepeemm

+0

謝謝。我開始編寫僞代碼,然後做了Java,但沒有檢查它是否編譯 - 在沒有IDE的情況下直接寫入。 –

+0

我在將它轉換爲Python後試用了這段代碼。所以深度決定了Vector的大小,也就是循環中有多少個嵌套,但這些矢量的值應該是多少?看起來像Length應該總是深度的(例如[3,3,3]),而Counter就是它在循環中的任何東西(對於[0,1,2],如果你只想從0開始並在max之後停止-1)? – ackmondual

1

我創建了這個程序來顯示卡片的所有不同組合(非重複)。它使用循環遞歸。也許它可以幫助你。

//I'm lazy, so yeah, I made this import... 
import static java.lang.System.out; 

class ListCombinations { 

    //Array containing the values of the cards 
    static Symbol[] cardValues = Symbol.values(); 

    //Array to represent the positions of the cards, 
    //they will hold different card values as the program executes 
    static Symbol[] positions = new Symbol[cardValues.length]; 

    //A simple counter to show the number of combinations 
    static int counter = 1; 

    /*Names of cards to combine, add as many as you want, but be careful, we're 
    talking about factorials here, so 4 cards = 24 different combinations (4! = 24), 
    but 8 cards = 40320 combinations and 13 cards = 6.23 billion combinations!*/ 
    enum Symbol { 
     AofSpades, TwoofSpades, ThreeofSpades, FourofSpades 
    } 

    public static void main(String args[]) { 

     //I send an argument of 0 because that is the first location which 
     //we want to add value to. Every recursive call will then add +1 to the argument. 
     combinations(0); 
    } 

    static void combinations(int locNumber) { 

     /* I use a recursive (repeating itself) method, since nesting for loops inside 
     * each other looks nasty and also requires one to know how many cards we will 
     * combine. I used 4 cards so we could nest 4 for loops one after another, but 
     * as I said, that's nasty programming. And if you add more cards, you would 
     * need to nest more for loops. Using a recursive method looks better, and gives 
     * you the freedom to combine as many cards as you want without changing code. */ 

     //Recursive for loop nesting to iterate through all possible card combinations 
     for(int valueNumber = 0; valueNumber < cardValues.length; valueNumber++) { 
      positions[locNumber] = cardValues[valueNumber]; 
      if (locNumber < (cardValues.length-1)) { 
       combinations(locNumber + 1); 
      } 

      //This if statement grabs and displays card combinations in which no card value 
      // is repeated in the current "positions" array. Since in a single deck, 
      // there are no repeated cards. It also appends the combination count at the end. 
      if (locNumber == (cardValues.length-1) && repeatedCards(positions)) { 
       for (int i = 0; i < cardValues.length; i++) { 
       out.print(positions[i]); 
       out.print(" "); 
       } 
       out.printf("%s", counter); 
       counter++; 
       out.println(); 
      } 
     } 
    } 

    static boolean repeatedCards(Symbol[] cards) { 

     /*Method used to check if any cards are repeated in the current "positions" array*/ 

     boolean booleanValue = true; 

     for(int i = 0; i < cardValues.length; i++) { 
      for(int j = 0; j < cardValues.length; j++) { 
       if(i != j && cards[i] == cards[j]) { 
        booleanValue = false; 
       } 
      } 
     } 
     return booleanValue; 
    } 
}