2013-10-16 15 views
15

mam metodę, która musi wykonać następujące czynności:Jak n zagnieżdżać dla pętli rekursywnie?

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

Chciałbym określić liczbę zagnieżdżonych dla (w powyższym przypadku, chcę 15 zagnieżdżona dla tych). Czy istnieje sposób korzystania z programowania rekursywnego tutaj?

+14

Proszę, nie. Nie rób tego. –

+4

Po prostu stwórz metodę i pozwól, by zadzwonił 15 razy. To jest prawdziwa metoda rekurencyjna. – BalusC

+1

@SotiriosDelimanoljest wyjaśnienie, dlaczego? ;-) –

Odpowiedz

15

Tak. Można tego dokonać za pomocą programowania rekurencyjnego.

Zakładam, że nie lubisz zapisywać tych zagnieżdżonych forów w kodzie źródłowym - tak jak w twoim przykładzie, ponieważ jest to naprawdę brzydkie programowanie - jak wyjaśniają komentatorzy.

Poniższy (pseudo podobny do Javy) kod ilustruje to. Zakładam stałą głębokość dla zagnieżdżenia. W takim razie lubisz pętle nad wektorem całkowitym o wymiarach.

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

Tablica counters musi być zainicjowany 0 (Arrays.fill(counters,0)). Macierz musi być zainicjalizowana do liczby iteracji dla odpowiedniej pętli for.

Zakładam, że chcesz wykonać pewną operację w wewnętrznej pętli. Będę to nazwać performOperation(int[] counters); - zależy to od wielowymiarowego licznika, tj. Liczników zewnętrznych forów.

Następnie można uruchomić zagnieżdżone pętle wywołując

nestedLoopOperation(counters, length, 0); 

gdzie

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

W twoim przypadku Twój System.out.println() byłoby

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

W twoim wewnętrznym wywołaniu funkcji brakuje parametru 'length'. – Teepeemm

+0

Dziękuję. Zacząłem pisać pseudo-kod, potem zrobiłem Javę, ale nie sprawdziłem, czy się kompiluje - pisałem bezpośrednio tutaj bez IDE. –

+0

Wypróbowałem ten kod po przekonwertowaniu go na język Python. Głębokość określa rozmiar wektora, czyli liczbę gniazd w pętli, ale jakie wartości powinny mieć te wektory?Wygląda na to, że Długość powinna zawsze być głęboka (np. [3, 3, 3]), podczas gdy Counter jest tym, czym jest w pętli (dla [0, 1, 2] jeśli chcesz zacząć od 0 i zatrzymać po maks. -1)? – ackmondual

1

I stworzyłem ten program, aby pokazać całą możliwą kombinację kart (bez powtarzania). Używa rekurencji dla pętli. Może to ci pomoże.

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