Jede Art von Iteration durch irgendeine Datenstruktur kann mit Rekursion durchgeführt werden.
function factorial($n) {
$result = $n < 0 ? -1 : 1;
for($i = abs($n), $i > 1; $i--) {
$result *= $i;
}
return $result;
}
kann geschrieben werden:
function factorial($n) {
$forHelper = function($result, $i) {
return $i === 1 ? $result : $forHelper($result * $i, $i - 1);
}
return $forHelper($n < 0 ? -1 : 1, abs($n));
}
Rekursion Dies nennt man Schwanz In der Tat kann man jede Schleife wie for
, while
, do while
, foreach
, etc so einfach Rekursion ersetzen konstruieren. In einigen Sprachen erzeugen die beiden obigen einen sehr ähnlichen Laufzeitcode, aber nicht PHP. Es verwendet für jeden Anruf etwas Speicher. Für mich sind beide gleichermaßen lesbar, aber ich wette, die meisten Programmierer würden es einfacher mit der Schleife finden, besonders wenn sie verschachtelt wird.
Einige Algorithmen, wo Sie eine Grafik oder Baum iterieren eine einfachere Version haben Rekursion anstatt Iteration:
function treeDepth($node) {
if($node === null) {
return 0;
} else {
return 1 + max(treeDepth($node->left), treeDepth($node->right));
}
}
Eine hier iterative Lösung eine gewisse Art und Weise der Verfolgung der Orte, braucht es brauchen würde, zu besuchen und Sie führen also einen gewissen Verwaltungsaufwand aus, der von der rekursiven Version automatisch behandelt wird.
function treeDepth($node) {
$max = 0;
$backtrack = [[0, $node]];
while(count($backtrack)) {
list($depth, $node) = array_pop($backtrack);
while($node !== null) {
array_push($backtrack, [++$depth, $node->right]);
$node = $node->left;
}
$max = max($max, $depth);
}
return $max;
}
Die Beschränkung hängt von der Sprache ab. In PHP wird für jeden Aufrufrahmen, der nicht für eine einfache Schleife reserviert ist, etwas Speicher reserviert. Das Node-Traversal verwendet immer Speicher, da der Prozess von Natur aus rekursiv ist.
Letztendlich sollten Sie so programmieren, dass Ihr Code so klar wie möglich ist, ohne an Optimierung zu denken. Verwenden Sie Schleifenkonstrukte dort, wo sie am klarsten sind und Rekursion dort, wo sie am klarsten ist. Nur wenn Sie tatsächlich auf Leistungsprobleme stossen, sollten Sie die Teile, die am meisten Zeit verbrauchen, profilieren und neu schreiben. Ich verwende den ursprünglichen Code als Kommentar, wenn er kurz ist und dokumentiert, was in der komplexeren iterativen Version tatsächlich passiert. In PHP-Funktionen sind Anrufe selbst teuer.
Willkommen bei SO! Werfen Sie einen Blick auf diesen Beitrag für Tipps, wie Sie gute Fragen schreiben L https://stackoverflow.com/help/how-to-ask –
In den meisten Fällen, aber nicht alle können Sie regelmäßige Schleifen anstelle von Rekursion verwenden. Rekursion erlaubt kleineren (sauberen?) Code im Vergleich zu einer Loop-Lösung. Siehe: https://stackoverflow.com/questions/1094679/is-there-a-problem-that-has-only-a-recursive-solution & https://stackoverflow.com/questions/660337/recursion-vs- Schleifen – Alex
Grundsätzlich jedes Problem, bei dem eine Teillösung zu dem gleichen Problem mit unterschiedlichen Eingaben führt; z.B. Münzwechsel: Ich habe einige Münzen und muss 5,23 € bezahlen; Ich benutze eine 2-Euro-Münze, und dann habe ich eine kleinere Sammlung von Münzen und ich muss 3,23 Euro zahlen; oder ich fange mit einer 1-Euro-Münze an und muss noch 4,23 Euro bezahlen. Partitionierung ist ein weiterer offensichtlicher Kandidat für Rekursion. Oder Permutationen generieren. – m69