Java - Ich vestehe diese äußerst komplizierte Schleife/Methode nicht. Kann sie mir wer erklären?

...komplette Frage anzeigen ssdfsd - (Programm, programmieren, Informatik)

7 Antworten

Weil dies das Wesen einer einstufigen Rekursion ist. Alles was nach dem rekursiven Aufruf in der Funktion geschieht, geschieht erst, wenn der rekursive Aufruf zurückkehrt.

Der rekursive Aufruf ist so positioniert, dass die Ausgabe immer erst erfolgt, wenn der rekursive Aufruf zurückkehrt.

Das heißt:

Die Funktion wird mit 0 aufgerufen. 0 != 6 => Rekursion.
Die Funktion wird mit 1 aufgerufen. 1 != 6 => Rekursion.
Die Funktion wird mit 2 aufgerufen. 2 != 6 => Rekursion.

...

Die Funktion wird mit 6 aufgerufen. 6 == 6 => Return ohne Ausgabe.
Der Aufruf für 5 gibt 5 aus und kehrt zurück.
Der Aufruf für 4 gibt 4 aus und kehrt zurück.

...

Der Aufruf für 0 gibt 0 aus und kehrt zurück.


2flawless2 17.05.2017, 19:38

Ja genau, bei 6 kehrt die Methode zum Aufrufer zurück und damit müsste die Methode Geschichte sein, stattdessen gibt sie noch  irgendwelche Zahlen aus???

0
ohwehohach 17.05.2017, 20:52
@2flawless2

Dieser rekursive Aufruf ja - aber dann geht die Abarbeitung der aufrufenden Methode weiter. Und das ist down(5).

Nach dem rekursiven Aufruf wird doch noch per println was ausgegeben! Das wird auf jeden Fall ausgeführt (außer, wenn die Funktion mit Parameterwert 6 aufgerufen wird, denn dann wird vorher per return die Abarbeitung verlassen).

Der Debugger im Einzelschrittmodus hilft vermutlich...

0
Plokapier 17.05.2017, 20:52
@2flawless2

Natürlich nicht. Die Methode, die mit 6 aufgerufen wurde, gibt nichts zurück, da sie ja in die Abbruchbedingung geht. Es liegen jedoch noch 6 andere Funktionen auf dem Stack, die alle nacheinander ausgeführt werden und eine Ausgabe auf die Konsole tätigen.

0
2flawless2 17.05.2017, 21:29

Aber, wenn "return" aktiviert wird, wird doch die Methode beendet. Wo
kann ich jemanden in meiner Nähe finden, der mir das für fünf Euro
erklärt. Ich bin eigentlich nicht dumm, nur komme ich nicht dahinter.

0
ohwehohach 18.05.2017, 08:36
@2flawless2

Return beendet die aktuell ausgeführte Funktion und kehrt zum Aufrufer zurück. Der Aufrufer ist in diesem Fall eben down(5). Und der Aufrufer von down(5) ist down(4) und so weiter.

Denke Dir Funktionen als Boxen. Return springt aus der aktuellen Box raus in die Box darüber. down(5) ist aber eine andere Box als down(6) oder down(3) oder down(1) - return springt nur aus der aktuellen Box raus.

0

Erster Durchlauf:

down2() wird mit 0 aufgerufen. down2() ruft down2() mit dem Argument 1 auf. Die Konsolenausgabe darunter wird noch nicht ausgeführt.

Zweiter Durchlauf:

down2() wird mit 1 aufgerufen. down2() ruft down2() mit dem Argument 2 auf. Die Konsolenausgabe darunter wird noch nicht ausgeführt.

und so weiter...

Fünfter Durchlauf:

down2() wird mit 6 aufgerufen und beendet sich gleich wieder. Die ganzen vorherigen Aufrufe von down2() sind aber allesamt noch nicht beendet, deswegen kommen nun die Konsolenausgaben.

Vielleicht wird es ersichtlicher, wenn du dir am Anfang von down2 eine Ausgabe

system.out.printlin("Calling down2 with n = " + n);

setzt.

2flawless2 17.05.2017, 19:42

Das ist der Teil, den ich nich verstehe

Die ganzen vorherigen Aufrufe von down2() sind aber allesamt noch nicht beendet, deswegen kommen nun die Konsolenausgaben.

0
2flawless2 17.05.2017, 19:46

Vielleicht wird es ersichtlicher, wenn du dir am Anfang von down2 eine Ausgabe


system.out.printlin("Calling down2 with n = " + n);

Das hilft mir leider nicht weiter

0
2flawless2 17.05.2017, 21:28

Aber, wenn "return" aktiviert wird, wird doch die Methode beendet. Wo kann ich jemanden in meiner Nähe finden, der mir das für fünf Euro erklärt. Ich bin eigentlich nicht dumm, nur komme ich nicht dahinter.

0

Rufe down2(6) auf und verfolge genau, was passiert. Hier wird die Funktion sofort beendet. Warum? Weil n 6 ist, gilt nun n==6.

Rufe nun down2(5) auf und beobachte wieder exakt, was geschieht. Diesmal greift das "if" nicht! Nun wird zuerst down2(5+1) aufgerufen (das war aber down2(6)), dort geschah aber nichts, danach wird  "5," ausgegeben. Ergo: down2(5) liefert "5,".

Rufe nun zum Verständnis noch down2(4) auf und verfolge, was geschieht. ist 4==6?? Nein, also wird down2(5) aufgerufen. Dies gibt aber "5," aus (hatten wir ja gerade besprochen). Danach (erst danach!) wird "4," ausgegeben. Zusammenfassend wird beim Aufruf von down2(4) also "5,4," ausgegeben.

Macht's klick?


Kannst du in deiner Entwicklungsumgebung ein Programm schrittweise ablaufen lassen und dir dabei den Aufrufstack und Werte von Variablen anzeigen lassen? Das ist m. E. die einfachste Methode, das zu verstehen.

Sonst kannst du auch mal 6 Prozeduren schreiben ungefähr folgender Form (ich lasse einige Details des Programmcodes weg, bitte ergänzen):

main() {
Rekursionsfunktion0();
}

Rekursionsfunktion0() {
Rekursionsfunktion1();
print(0);
}

Rekursionsfunktion1() {
Rekursionsfunktion2();
print(1);
}

Rekursionsfunktion2() {
Rekursionsfunktion3();
print(2);
}

Rekursionsfunktion3() {
Rekursionsfunktion4();
print(2);
}

Rekursionsfunktion4() {
Rekursionsfunktion5();
print(4);
}

Rekursionsfunktion5() {
Rekursionsfunktion6();
print(5);
}

Rekursionsfunktion6() {
return;
}

Weil der rekursive Aufruf VOR dem println() steht.

2flawless2 17.05.2017, 19:34

weiß ich und sehe ich doch

0
triopasi 17.05.2017, 19:36
@2flawless2

Ja.. dann kommt man zum Ende der Rekursion, bevor irgendwas ausgegeben wird.

0
2flawless2 17.05.2017, 21:29

Aber, wenn "return" aktiviert wird, wird doch die Methode beendet. Wo
kann ich jemanden in meiner Nähe finden, der mir das für fünf Euro
erklärt. Ich bin eigentlich nicht dumm, nur komme ich nicht dahinter.

0
HylianGamer 17.05.2017, 22:17
@2flawless2

Ich seh, wo es bei dir hängt.

Aber, wenn "return" aktiviert wird, wird doch die Methode beendet

Ja, return wird aktiviert. Aber nur bei n==6. Dafür ist diese if-Abfrage da.

Und return wird nur für down2(6) ausgeführt. Nicht für die gesamte Rekursion. Nur für diesen einen Teilaufruf. down 6 ist fertig. Also springt es zurück. Aber nicht ganz am Anfang, sondern am Aufruf davor, nämlich zu down 5. down 5 gibt auf Konsole aus. down 5 ist fertig. Weiter mit down 4. Und so weiter.

0

In "down2(...)" wird "down2(...)" aufgerufen, bevor der Text ausgegeben wird. down(0) wartet also auf down(1). down(1) wartet auf down(2) usw.... down(5) ist dann sozusagen der erste Durchgang, der nicht mehr warten muss, da der ganze Spaß ja bei down(6) vorbei ist. Das heißt down(5) gibt den Text aus wodurch down(4) nicht mehr auf down(5) warten muss usw... Daher beginnt die Textausgabe also bei der 5 und geht dann so zurück zur 0.

Ich hoffe, ich habe das einigermaßen verständlich formuliert ^^

2flawless2 17.05.2017, 19:40

ich verstehe es nicht

0
xdxderich 17.05.2017, 19:44
@2flawless2

Beim zweiten Lesen meiner Antwort sehe ich auch nicht mehr so ganz durch  ¯\_(ツ)_/¯ 

Naja... Hier sind aber einige gute Antworten diesbezüglich. Eventuell hast du das mit dem "return" falsch aufgefasst. Dadurch wird nicht jede Methode beendet, sondern nur die mit dem Argument 6. Die anderen laufen trotzdem noch weiter und geben entsprechend die Nachrichten aus.

0
2flawless2 17.05.2017, 21:29

Aber, wenn "return" aktiviert wird, wird doch die Methode beendet. Wo
kann ich jemanden in meiner Nähe finden, der mir das für fünf Euro
erklärt. Ich bin eigentlich nicht dumm, nur komme ich nicht dahinter.

0

Also kompliziert ist das bei weitem nicht, dass ist für rekursion sogar viel zu trivial (außerdem ist das keine korrekte rekursive funktion sondern eine induktive Funktion)

Es wird n (0) aufgerufen
Dann n (1) (DIESER AUFRUF GESCHIEHT ABER BEI der ausführung von n (0)!
Dann n2
Dann n3
Dann n4
Dann n5
Dann n6

so n6 verlässt die methode. Da n6 bei n5 aufgerufen wurde, wird dort weitergemacht. Sodass dannach print n5 kommt usw.

ohwehohach 17.05.2017, 20:50

Was soll denn eine induktive Funktion sein? Eine rekursive Funktion zeichnet sich dadurch auf, dass sie sich selbst wieder aufruft, ggf. mit abweichenden Parametern. Somit ist dies eine korrekte rekursive Funktion.

0
2flawless2 17.05.2017, 21:29

Aber, wenn "return" aktiviert wird, wird doch die Methode beendet. Wo
kann ich jemanden in meiner Nähe finden, der mir das für fünf Euro
erklärt. Ich bin eigentlich nicht dumm, nur komme ich nicht dahinter.

0

Was möchtest Du wissen?