2009-11-15 12 views
6

Ich versuche, eine einfache Möglichkeit zur Handhabung von dynamischen geschachtelten Schleifen Ebene herauszufinden. Betrachten Sie die folgende Funktion, die 2 Parameter akzeptiert: Anzahl der Schleifen und Maximalwert.Dynamisch geschachtelte Schleifen Ebene

void PrintLoop(int maxloop, int maxvalue) 

PrintLoop(1,2); 
// output 
0 
1 

PrintLoop(2,2); 
// output 
0, 0 
0, 1 
1, 0 
1, 1 

PrintLoop(3,2); 
// output 
0, 0, 0 
0, 0, 1 
0, 1, 0 
0, 1, 1 
1, 0, 0 
1, 0, 1 
1, 1, 0 
1, 1, 1 

Etc ...

Gibt es eine Möglichkeit, eine Funktion zu schreiben, die diese „dynamische verschachtelte Schleifen“ Verhalten erzeugen kann?

Vielen Dank für jede Hilfe

+3

Angesichts der Funktion 'PrintLoop (m, n)', beobachten Sie, dass alles, was Sie tun, zählt von 0 bis 'n^m' in der Basis' n'. –

+0

Das sieht sehr nach einer Hausaufgabe aus, welchen Code hast du bisher probiert und wo steckst du fest? – mlibby

Antwort

9

Ja, es ist möglich, und dies kann ein Konzept der „recursion“ wird häufig verwendet, implementieren:

void PrintLoop(int maxloop, int maxvalue) 
{ 
    if (maxloop<=0) return ; 
    // print something here... 
    for (int i=0;i<maxmalue;i++){ 
     PrintLoop(maxloop-1, maxvalue); 
    } 
} 
+1

Nun, Rekursion ist ein * bedeutet * dies zu implementieren, nicht der Name des Konzepts. –

+0

Rekursion ist der Weg zu gehen, ja. Aber ich vermisse irgendwelche Druckanweisungen ... – Stephan202

+1

@ Stephan202, natürlich, ich * könnte * die Aussagen schreiben, aber irgendwas sagt mir, dass es eine Hausaufgabe ist, also bleibe ich lieber bei allgemeinen Ratschlägen ... –

0

In Ada Sie einen DECLARE Block tun könnten das nach dem Aufstehen Benutzereingabe; Setzen Sie Ihre Schleife dann auf 1 .. Read_In_Loop_Control_Value und dann auf eine verschachtelte Schleife, um Ganzzahlen von 1 .. Read_In_Number_Per_Line Wert zu drucken.

5

Pavel's answer zeigt, wie die Rekursion durchgeführt wird. Eine Funktion, die nur zwei Argumente benötigt (Anzahl der Schleifen und Maximalwert), hat jedoch nicht genügend Kontext, um die Zahlen wie in Ihrem Beispiel zu drucken. Dafür müssen Sie einige zusätzliche Informationen verfolgen. Eine Möglichkeit, dies zu tun, ist die folgende:

void _print_loop(int *values, int width, int cur_col, int max) { 
    if (cur_col == width) { 
    for (int i = 0; i < width; i++) { 
     printf("%d%c", values[i], (i < width - 1) ? ' ' : '\n'); 
    } 
    } else { 
    for (int i = 0; i < max; i++) { 
     values[cur_col] = i; 
     _print_loop(values, width, cur_col + 1, max); 
    } 
    } 
} 

void print_loop(int width, int max) { 
    int values[width]; 
    memset(values, 0, width * sizeof(int)); 
    _print_loop(values, width, 0, max); 
} 

Jetzt print_loop(3, 2) verhält sich wie erwartet.

Edit: eigentlich ein kann schreiben eine zwei Argument Funktion, dies zu tun, durch die Verwendung von static Variablen, die bei Empfang eines positiven width Argument initialisiert werden. Nach dieser Initialisierungsphase führt die Funktion dann ihre Rekursion mit negativen Werten durch. Offensichtlich ist der resultierende Code schrecklich, aber ich werde es trotzdem veröffentlichen, für die der Vollständigkeit halber:

void print_loop(int width, int max) { 
    static int max_width; 
    static int *values; 

    if (width > 0) { 
    max_width = width; 
    if ((values = calloc(width, sizeof(int))) == NULL) { 
     perror("calloc"); 
     exit(EXIT_FAILURE); 
    } 
    print_loop(-width, max); 
    free(values); 
    } 
    else if (width == 0) { 
    for (int i = 0; i < max_width; i++) { 
     printf("%d%c", values[i], (i < max_width - 1) ? ' ' : '\n'); 
    } 
    } 
    else { 
    for (int i = 0; i < max; i++) { 
     values[-width - 1] = i; 
     print_loop(width + 1, max); 
    } 
    } 
} 
+0

Danke für Ihre ausführliche Antwort. Ich habe erwartet, dass dieses Problem mit Rekursionen gelöst werden muss. Obwohl ich hoffte, dass es einen Mechanismus geben könnte, um es rein mit Iterationen zu tun.Die Programmiersprachen brauchen etwas update :) –

+0

Da * ist * eine ziemlich direkte Möglichkeit, es ohne Rekursion zu tun. Sehen Sie meinen Kommentar zu Ihrer ursprünglichen Frage. –

3

Sie Rekursion verwenden können, oder Sie können jeder Schleife des Staates ausdrücklich speichern und die Zustände in einer einzigen Schleife verwalten.

In diesem Fall bedeutet es, ein Array von Zählern zu speichern. Jede Ausführung der Hauptschleife rückt den innersten Zähler und alle äußeren Zähler vor, deren innere Nachbarn "überführen". Der höchste Zähler agiert als Wächter.

void printloop(int maxloop, int maxvalue) { 
    unsigned int counters[maxloop+1]; // C99 for the win 
    memset(counters, 0, sizeof(counters)); 

    while(!counters[maxloop]) { 
     int i; 
     char *sep=""; 
     for(i=maxloop; i-->0;) { 
      printf("%s%d",sep,counters[i]); 
      sep=","; 
     }; 
     printf("\n"); 
     for(i=0; counters[i]==maxvalue; i++) // inner loops that are at maxval restart at zero 
      counters[i]=0; 
     ++counters[i]; // the innermost loop that isn't yet at maxval, advances by 1 
    } 
} 
Verwandte Themen