2016-05-06 11 views
0

Ich bin ziemlich neu in der Programmierung und ich bin jetzt auf das Konzept der Rekursion gekommen. Ich habe ein paar grundlegende Aufgaben gelöst, aber wenn ich zur multiplen Rekursion komme, werde ich furchtbar verloren. Ich habe versucht, die folgende Rekursion mehrmals zu lösen, aber ich kann es einfach nicht richtig machen. Eine rekursive Methode wird mit den Argumenten "ABCD" und 2 aufgerufen, d. H. recMethod("ABCD", 2);.Was passiert, wenn Rekursion in einer Methode zweimal aufgerufen wird?

public void recMethod(String str, int n) { 
    if(n >= 0) { 
    recMethod(str, n – 1); 
    System.out.print(str.charAt(n)); 
    recMethod(str, n – 1); 
    } 
} 

Gibt es jemanden da draußen, der erklären kann, was vor sich geht? Der erste rekursive Aufruf verwirrt mich wirklich.

+0

Es gibt keine Rekursion in Ihrer Frage. –

+0

Ich habe den Namen der Methode geändert, um das Beispiel klarer zu machen, habe aber vergessen, den Namen innerhalb der Methode zu ändern. – SirDanceAlot

Antwort

3

Der beste Weg, die Rekursion zu verstehen, wie für mich auf dem Papier Zeile für Zeile zu schreiben ist. Was ich jetzt für deinen Fall getan habe. enter image description here

Bitte versuchen, das gleiche zu tun, und zögern Sie nicht, Fragen zu stellen, ich hoffe, es hilft!

4

Das Wichtigste über Rekursion ist, dass es nichts besonderes ist. Wie bei allem in einem Verfahren braucht es eine Anweisung zu beenden, bevor die nächste Anweisung ausgeführt werden kann:

public void someMethod() { 
    someOtherMethod(); 
    someLastMethod(); 
} 

Mit Blick auf meinem Beispiel ist es offensichtlich, dass someLastMethod wird nach someOtherMethod beendet hat aufgerufen werden. Es ist wirklich egal, wenn Sie someOtherMethod durch etwas rekursives ersetzen. Es muss beendet werden, bevor someLastMethod aufgerufen werden kann. Wenn wieder auf Ihrer rekursive Methode suchen:

public void recMethod(String str, int n) { 
    if(n >= 0) { 
     recMethod(str, n – 1); 
     System.out.print(str.charAt(n)); 
     recMethod(str, n – 1); 
    } else { // base case added for clarity 
     return; 
    } 
} 

Für jeden Anruf, wo n >= 0, bevor die System.out.print Methode um den Anruf zu recMethod genannt wird, hat aufgerufen werden. Jeder Anruf zu recMethod hat seine eigenen n und str so können sie verschiedene Methoden in Betracht gezogen werden völlig außer ihrem Code ist ‚sehr ähnlich‘.

Jeder Aufruf entspricht entweder dem Basisfall oder benötigt das Ergebnis der gleichen Methode mit n dekrementiert. Ich möchte also vom Basisfall ausgehen und mich rückwärts arbeiten, wenn n -1 ist. Stellen Sie sich vor, Sie rufen recMethod("ABCD",-1) was würde passieren? Nun, es druckt nichts oder "".

Ich sehe dann und es ruft den Basisfall, den wir wissen, tut nichts, dann druckt "A" und dann ruft es das gleiche wie die erste Anweisung, die wiederum nichts tut. So druckt er „A“

Wenn wir recMethod("ABCD",1) suchen. Wir wissen, dass es recMethod("ABCD",0) nennt, die „A“ druckt, dann druckt es „B“, dann recMethod("ABCD",0) nennen, die „A“ druckt. So druckt es "ABA"

Wenn wir recMethod("ABCD",2) betrachten. Wir wissen, dass es ruft recMethod("ABCD",1), die "ABA" druckt, dann druckt es "C", dann rufen Sie recMethod("ABCD",1), die "ABA" druckt. So druckt es "ABACABA"

Wenn wir recMethod("ABCD",3) betrachten. Wir wissen, dass es recMethod("ABCD",2) nennt die „ABACABA“ druckt, dann druckt es „D“, rufen dann recMethod("ABCD",2), den Druck „ABACABA“. So druckt es "ABACABADABACABA"

Da "abcd".charAt(4) nicht funktioniert, macht es keinen Sinn, weiterzugehen.Vielleicht sollte der Code einen Test dafür haben oder vielleicht sollte es privat sein und ein öffentliches haben ohne n das garantiert n geht nie über str Grenzen hinaus?

Wenn Sie sind, ein Verfahren zu machen, die rekursiv Sie das gleiche tun funktioniert.

  1. Was sollte für den Basisfall passieren. (Wie sollte es aufhören)

  2. Was passieren soll, wenn es nicht das Basismodell ist ausgedrückt, als ob die Methode funktioniert wie vorgesehen. Der Haken hier ist, dass Sie sicherstellen müssen, dass jeder Aufruf der gleichen Methode hier ein etwas einfacheres Problem ist, bei dem die Rekursion zwangsläufig einen Basisfall trifft, oder Sie erhalten eine unendliche Rekursion!

Das ist es! Es wird klappen.

+0

schöne und klare Erklärung –

+0

Idealerweise, wenn es sich um eine Iterationslösung handelte, würde das Auftreffen auf den Basisfall den Fluss aus der Methode herausnehmen. Aber in diesem Fall, wenn es den Basisfall trifft, bewegt es sich stattdessen zu dem Code nach der rekursiven Methode. Recht? – underdog

+0

@underdog Mit einer Schleife könnten Sie einen Earlt-Exit machen, der Ihre Backtracking-Struktur ignoriert. Bei der Rekursion können Sie das erste Ergebnis untersuchen, um festzustellen, ob Sie es zurückgeben oder das zweite tun möchten. Das wird es genauso machen. In Scheme können Sie sogar 'call/cc' verwenden, so dass Sie Wartezeiten im Call-Stack überspringen können, wenn Sie das Endergebnis kennen und die Ähnlichkeiten größer wären. – Sylwester

Verwandte Themen