Rekursiv Funktion



  • Hallo Freunde,

    ich hab den folgenden Code,

    #include <iostream>
    using namespace std;
    
    void print(int n, int k) {
        if (n < k) return;
        cout << n + 1;
        print(n - 1, k);
        cout << n - 1;
    }
    
    int main() {
        print (4, 1);
    return 0;
    }
    

    die Ausgabe ist;

    5
    4
    3
    2
    0
    1
    2
    3

    ich verstehe aber nicht warum ich diese Ausgabe erhalte, könnte mir bitte jemand erklären warum wird die Schleife nicht beendet, obwohl n nach 4 Wiederholung kleiner als k ist?

    Danke im Voraus
    LG



  • Welche Schleife? Und hast Du bedacht, dass die vorherigen Aufrufe der Funktion auch beendet werden müssen?



  • Oder ein anderer Ansatz, Rekursion zu erklären: Stell Dir vor, es gibt jede Menge Funktionen:

    void print41() {
        if (4 < 1) return;
        cout << 4 + 1;
        print31();
        cout << 4 - 1;
    }
    
    void print31() {
        if (3 < 1) return;
        cout << 3 + 1;
        print21();
        cout << 3 - 1;
    }
    

    etc.

    Hilft das?



  • SG1 schrieb:

    Welche Schleife? Und hast Du bedacht, dass die vorherigen Aufrufe der Funktion auch beendet werden müssen?

    Mit der Schleife meine ich die Rekursiv Funktion, den Code habe ich nicht selber geschrieben, sonder als eine Aufgabe von der Uni bekommen. Deine Frage habe ich leider nicht ganz verstanden tut mir leid bin ein Anfänger 😞



  • Wenn eine Funktion (print) verlassen wird, dann kehrt das Programm zur rufenden Funktion zurück. Und zwar hinter dem Aufruf.
    Und da steht noch jeweils ein cout

    void print(int n, int k) {
        if (n < k) return;
        cout << n + 1;
        print(n - 1, k);         --->
                                       void print(int n, int k) {
                                           if (n < k) return;
                                           cout << n + 1;
                                           print(n - 1, k);           --->    weiter print Aufrufe
                                                                     <---
                                           cout << n - 1;
                                 <---  }
        cout << n - 1;
    }
    


  • DirkB schrieb:

    Wenn eine Funktion (print) verlassen wird, dann kehrt das Programm zur rufenden Funktion zurück. Und zwar hinter dem Aufruf.
    Und da steht noch jeweils ein cout

    void print(int n, int k) {
        if (n < k) return;
        cout << n + 1;
        print(n - 1, k);         --->
                                       void print(int n, int k) {
                                           if (n < k) return;
                                           cout << n + 1;
                                           print(n - 1, k);           --->    weiter print Aufrufe
                                                                     <---
                                           cout << n - 1;
                                 <---  }
        cout << n - 1;
    }
    

    Danke für die Antwort. Ich hab es aber leider noch immer nicht ganz begriffen, deshalb habe ich den Code so geändert, damit ich sehen kann was und wo passiert.

    #include <iostream>
    using namespace std;
    void print(int n, int k) {
    
    	cout << "before n = " << n << endl;
    	cout << "before k = " << k << endl;
    	if (n < k) return;
    	cout << n + 1 << " start" << endl;
    	cout << "after n = " << n << endl;
    	cout << "after k = " << k << endl;
    	print(n - 1, k);
    	cout << n - 1 << " end" << endl;
    
    }
    int main() {
    	print(4, 1);
    	system("pause");
    }
    
    bevor n = 4
    bevor k = 1
    5 start
    after n = 4
    after k = 1
    bevor n = 3
    bevor k = 1
    4 start
    after n = 3
    after k = 1
    bevor n = 2
    bevor k = 1
    3 start
    after n = 2
    after k = 1
    bevor n = 1
    bevor k = 1
    2 start
    after n = 1
    after k = 1
    bevor n = 0
    bevor k = 1
    0 ende
    1 ende
    2 ende
    3 ende
    Drücken Sie eine beliebige Taste . . .
    

    ich verstehe nicht, wieso beendet das Program bei der 21. Zeile nicht, es muss ja return; ausgeben und beenden 😞



  • yasahan schrieb:

    ich verstehe nicht, wieso beendet das Program bei der 21. Zeile nicht, es muss ja return; ausgeben und beenden 😞

    return beendet die AKTUELLE Funktion und kehrt zurück zur aufrufenden Funktion. Wie oft wurde die print-Funktion aufgerufen? 5x wenn ich das grad richtig sehe. Also kehre ich 4x zurück zur print-Funktion und 1x zurück zur main.

    Mir hilft es, wenn ich mir eine Rekursion einfacher vor Augen halte. Ich denke mir eine Rekursion einfach als Gleichung, z.B.
    Fakultät(4) = 4 * Fakultät(3)
    Der Punkt ist jetzt, mich interessieren die anderen Rekursionaufrufe gar nicht mehr, weil ich mein Problem anhand der Gleichung richtig definiert habe.
    Das einzige was mich jetzt noch interessiert, ist eine Abbruchbedingung:
    Fakultät(0) = 1

    Was ich sagen will, wenn ich die Gleichung und die Abbruchbedingung definiere, ist mein Rekursion komplett. Ich weiß, dass sie stimmt und muss mir im Kopf nicht 100 Funktionaufruf-Schritte durchdenken. Keine Ahnung, ob du verstehst, was ich sagen will? Kann sein, dass ich mich kompliziert ausgedrückt habe.

    z.B. wollte ich letztens den Inhalt eines HTML-Tags und alle Inhalte seiner Kinder in einem string haben. Dann mache ich einfach:
    Inhalt(Tag) = Inhalt(Kind-Tag) + eigener Inhalt
    Abbruchbedingung: Inhalt(Tag) = Leer
    Wenn ich mir das nun im Kopf durchspinnen würde, z.B. bei dem Quellcode dieses Threads, würde ich ja blöd werden....

    Du musst eben nun dein Problem in eine Gleichung fassen.



  • out schrieb:

    yasahan schrieb:

    ich verstehe nicht, wieso beendet das Program bei der 21. Zeile nicht, es muss ja return; ausgeben und beenden 😞

    return beendet die AKTUELLE Funktion und kehrt zurück zur aufrufenden Funktion. Wie oft wurde die print-Funktion aufgerufen? 5x wenn ich das grad richtig sehe. Also kehre ich 4x zurück zur print-Funktion und 1x zurück zur main.

    Mir hilft es, wenn ich mir eine Rekursion einfacher vor Augen halte. Ich denke mir eine Rekursion einfach als Gleichung, z.B.
    Fakultät(4) = 4 * Fakultät(3)
    Der Punkt ist jetzt, mich interessieren die anderen Rekursionaufrufe gar nicht mehr, weil ich mein Problem anhand der Gleichung richtig definiert habe.
    Das einzige was mich jetzt noch interessiert, ist eine Abbruchbedingung:
    Fakultät(0) = 1

    Was ich sagen will, wenn ich die Gleichung und die Abbruchbedingung definiere, ist mein Rekursion komplett. Ich weiß, dass sie stimmt und muss mir im Kopf nicht 100 Funktionaufruf-Schritte durchdenken. Keine Ahnung, ob du verstehst, was ich sagen will? Kann sein, dass ich mich kompliziert ausgedrückt habe.

    z.B. wollte ich letztens den Inhalt eines HTML-Tags und alle Inhalte seiner Kinder in einem string haben. Dann mache ich einfach:
    Inhalt(Tag) = Inhalt(Kind-Tag) + eigener Inhalt
    Abbruchbedingung: Inhalt(Tag) = Leer
    Wenn ich mir das nun im Kopf durchspinnen würde, z.B. bei dem Quellcode dieses Threads, würde ich ja blöd werden....

    Du musst eben nun dein Problem in eine Gleichung fassen.

    Ach jetzt verstehe ich es! Vielen Dank für Ihr Geduld! 🙂


Log in to reply