2016-07-23 8 views
1

Ich bin in Rekursion und ich wollte eine einfache Sache tun, wie eine Zeichenfolge umzukehren. Die Funktion funktioniert, aber ich verstehe nicht, wie und das macht mich sehr frustriert. (Rekursiven Teil)Umkehren einer Zeichenfolge mit Rekursion

function reverseString(myString) { 
if (myString == "") { 
    return ""; 
} 
else { 
    return reverseString(myString.substr(1)) + myString.charAt(0); 
}} 

Sagen wir, ich habe eine Zeichenfolge „abcd“. So ist die erste Schleife wäre:

"myString.substr (1)" macht aus "abcd" -> "bcd" und dann "charAt (0)" bekommt "b "; Das Ergebnis wäre "bcd + b"? Oder wird "myString.charAt (0)" ausgeführt, wenn die Rekursion beendet ist?

Ich bin völlig verloren ... wie sieht die ganze Prozedur aus?

+1

'substr' ändert nicht den Wert von' myString'. 'myString.charAt (0)' wäre '' a ''beim ersten Aufruf. – 4castle

+0

Wenn "a" beim ersten Anruf ist, dann wäre das Ergebnis nicht: abcd? –

+0

Nein, weil es mit dem Ende der Zeichenfolge verkettet wird. – 4castle

Antwort

-2

Nein, alle Parameter, die Sie an den rekursiven Aufruf übergeben, werden vor dem rekursiven Aufruf ausgewertet. (Klarstellung: das bedeutet nur myString.substr(1))

Sie sind richtig, myString.charAt(0) wird ausgeführt, nachdem Ihr rekursiver Aufruf zurückgegeben wird. Dies macht es komplexer als die sogenannte "Tail-Rekursion" oder "Kopfrekursion", bei der der rekursive Aufruf die letzte bzw. erste Operation in Ihrer rekursiven Funktion ist. Das Schreiben einer tailrekursiven oder kopfrekursiven Funktion kann bestimmten Compilern helfen, effizienteren Code zu erzeugen, und es hilft auch, Ihre Funktion verständlicher zu machen, aber es ist nicht "erforderlich".

Hier ist, wie es aussieht:

abcd 
bcd + a 
cd + ba 
d + cba 
dcba 
+0

Die Lesbarkeit ist eine Frage der Meinung. In einer funktionalen Programmiersprache (wo Rekursion stark verwendet wird), wäre dies vollkommen sinnvoll. – 4castle

+0

JavaScript hat keinen Compiler. – 4castle

+0

Ich mochte nicht, weil ich nicht genug Ruf habe. –

0

myString nicht geändert, wenn Sie die substr-Methode aufrufen. Diese

var mystring = 'abcd'; 
mystring.substr(1); 

console.log(mystring) // abcd 

bedeutet, dass jeder rekursive Aufruf rufen Sie eine brandneue String mit dem ersten Zeichen bis zum Ende der Schnur bewegt.

Erster Aufruf: recursiveString (bcd) + a

Zweiter Aufruf: recursiveString (cd) + b

Dritte Aufforderung: recursiveString (d) + c

Letzter Aufruf: recursiveString ("") + d

Erinnern Sie sich daran, dass jeder rekursive Aufruf ein Zeichen und dann eine Funktion zurückgibt, um mehr von ihnen abzurufen. Das bei jedem Aufruf zurückgegebene Zeichen erscheint nach der Funktion.

So baut die Funktion die Zeichenfolge wie: "" -> d -> c -> b -> a

+0

Ja, danke, ich verstehe es jetzt. Es hat gerade vor ein paar Minuten in meinem Kopf geklickt. –

3

„myString.substr (1)“macht von "ABCD" -> "bcd" und dann "charAt (0)" bekommt "b";

Nein, myString.substr(1) gibt einen neuen String mit dem Wert "bcd", den Wert von myString nicht ändert, so dass, wenn myString.charAt(0) der Wert genannt wird "a" zurückgegeben wird, weil es die ursprüngliche Zeichenfolge mit dem Wert indiziert "abcd"

+0

Ja, danke. Ich habe es jetzt nach einigen Tests mit console.log bekommen. –

1

Blick darauf, wie diese bewertet

Rückkehr Reverse (myString.substr (1)) + myString.charAt (0);
Schritt 1: zurückgeben reverseString ("bcd") + a;
Schritt 2: zurück reverseString ("cd") + b + a;
Schritt 3: zurück reverseString ("d") + c + b + a;
Schritt 4: zurück reverseString ("") + d + c + b + a;

+0

Ja, danke, ich verstehe es jetzt. Es hat gerade vor ein paar Minuten in meinem Kopf geklickt. –

0

Ich denke, es hilfreicher ist es in der Reihenfolge zu suchen, in dem die Dinge zurück von den (verschachtelten) rufen zu Reverse, da sie rief in Reverse hält, bis sie in einem leeren String geht - das ist der Punkt es fängt an, Dinge zurückzugeben.

call reverseString("abcd") 
    call reverseString("bcd") 
    call reverseString("cd") 
     call reverseString("d") 
     call reverseString("") 
      return "" 
     add "d" then return 
     add "c" then return 
    add "b" then return 
    add "a" then return 
+0

Danke, ich habe es schon verstanden. Ich habe auch ein Video von Computerphile gesehen, das half, den Stapel zu verstehen. (oder der Code, den du geschrieben hast) –

+0

Ich liebe auch Rekursion, also brauchte ich eine Weile, um es herauszufinden. Aber es ist auch großartig für Stapelüberläufe :) – Adrien

+0

p.s. Wenn du für mich gearbeitet hättest, würdest du in Schwierigkeiten geraten, das ist ein ziemlich schrecklicher Gebrauch von Heap (bestenfalls 1 Alloc und Free pro Char) und Stack (prob explodieren, wenn du eine 64k-String gibst).Das Umkehren einer Zeichenkette sollte an Ort und Stelle erfolgen, aber ich verstehe die Attraktivität der Rekursion durch eine intellektuelle Übungs-POV – Adrien