Ich weiß, was Rekursion ist (wenn ein Patten in sich selbst wieder auftritt, normalerweise eine Funktion, die sich nach einem ausbruchbedingten ... richtig? Auf einer seiner Linien aufruft), und ich kann rekursive Funktionen verstehen, wenn ich sie genau studiere. Mein Problem ist, wenn ich neue Beispiele sehe, bin ich anfangs immer verwirrt. Wenn ich eine Schleife oder ein Mapping, Zippen, Verschachteln, polymorphes Aufrufen usw. sehe, weiß ich, was passiert, wenn ich es mir nur ansehe. Wenn ich rekursiven Code sehe, lautet mein Gedankenprozess normalerweise "wtf is this?" gefolgt von 'oh, es ist rekursiv' gefolgt von 'Ich denke, es muss funktionieren, wenn sie sagen, dass es funktioniert.'
Haben Sie also Tipps / Pläne / Ressourcen zum Aufbau von Fähigkeiten in diesem Bereich? Rekursion ist eine Art seltsames Konzept, daher denke ich, dass die Art und Weise, wie es angegangen werden soll, ebenso seltsam und unauffällig sein kann.
Antworten:
Beginnen Sie mit etwas Einfachem und zeichnen Sie es mit Bleistift und Papier nach. Ernsthaft. Ein guter Ausgangspunkt sind Tree-Traversal-Algorithmen, da sie mithilfe von Rekursion viel einfacher zu handhaben sind als reguläre Iterationen. Es muss kein kompliziertes Beispiel sein, sondern etwas, das einfach ist und mit dem Sie arbeiten können.
Ja, es ist seltsam und manchmal kontraintuitiv, aber sobald es klickt, sagt man "Eureka!" du wirst dich fragen, wie du es vorher nicht verstanden hast ! ;) Ich schlug Bäume vor, weil sie (IMO) die am einfachsten zu verstehende Struktur in der Rekursion sind und mit Bleistift und Papier leicht zu bearbeiten sind. ;)
quelle
Ich empfehle Scheme mit dem Buch The Little Lisper. Sobald Sie damit fertig sind, werden Sie die Rekursion tief im Inneren verstehen. Fast garantiert.
quelle
Ich empfehle auf jeden Fall SICP. Schauen Sie sich auch die Einführungsvideos der Autoren an . Sie sind unglaublich aufschlussreich.
Ein anderer Weg, der nicht so eng mit dem Programmieren zusammenhängt, ist das Lesen von Gödel, Escher, Bach: Ein ewiger goldener Zopf von Hofstadter. Sobald Sie damit fertig sind, sieht die Rekursion so natürlich aus wie die Arithmetik. Sie werden auch überzeugt sein, dass P = nP und Sie werden Denkmaschinen bauen wollen - aber es ist ein Nebeneffekt, der im Vergleich zu den Vorteilen so gering ist.
quelle
Im Wesentlichen kommt es nur auf die Übung an ... Nehmen Sie allgemeine Probleme (Sortieren, Suchen, mathematische Probleme usw.) und sehen Sie, wie diese Probleme gelöst werden können, wenn Sie eine einzelne Funktion mehrmals anwenden.
Die schnelle Sortierung verschiebt beispielsweise ein Element in einer Liste in zwei Hälften und wendet sich dann erneut auf jede dieser Hälften an. Wenn die anfängliche Sortierung stattfindet, ist es nicht wichtig, die beiden Hälften an diesem Punkt zu sortieren. Vielmehr nimmt man das Pivot-Element und legt alle Elemente, die kleiner als dieses Element sind, auf eine Seite und alle Elemente, die größer oder gleich sind, auf die andere Seite. Ist es sinnvoll, wie es sich an diesem Punkt rekursiv selbst aufrufen kann, um die beiden neuen kleineren Listen zu sortieren? Das sind auch Listen. Einfach kleiner. Aber sie müssen noch sortiert werden.
Die Kraft hinter der Rekursion ist die Idee der Teilung und Überwindung. Teilen Sie ein Problem wiederholt in kleinere Probleme auf, die von Natur aus identisch, aber nur kleiner sind. Wenn du das genug tust, kommst du irgendwann zu einem Punkt, an dem das einzige verbleibende Stück bereits gelöst ist, und du arbeitest dich einfach wieder aus der Schleife heraus, und das Problem ist gelöst. Studieren Sie die Beispiele, die Sie erwähnt haben, bis Sie sie verstanden haben. Es kann eine Weile dauern, aber irgendwann wird es einfacher. Versuchen Sie dann, andere Probleme aufzugreifen und eine rekursive Funktion zu erstellen, um sie zu lösen! Viel Glück!
EDIT: Ich muss auch hinzufügen, dass ein Schlüsselelement für die Rekursion die garantierte Fähigkeit der Funktion ist, stoppen zu können. Dies bedeutet, dass die Zerlegung des ursprünglichen Problems kontinuierlich kleiner werden muss und schließlich ein garantierter Haltepunkt vorhanden sein muss (ein Punkt, an dem das neue Teilproblem entweder lösbar oder bereits gelöst ist).
quelle
def factorial(number): """return factorial of number""" if number == 0: return 0 elif number == 1: return 1 else: return number * factorial(number - 1)
Persönlich denke ich, dass Ihre beste Wette durch Übung ist.
Ich habe mit LOGO Rekursion gelernt. Sie könnten LISP verwenden. Rekursion ist in diesen Sprachen selbstverständlich. Ansonsten können Sie es mit dem Studium von mathematischen Reihen und Reihen vergleichen, in denen Sie ausdrücken, was als nächstes basierend auf dem Vorherigen kommt, dh u (n + 1) = f (u (n)), oder mit komplexeren Reihen, in denen Sie mehrere Variablen und haben multiple Abhängigkeiten, zB u (n) = g (u (n-1), u (n-2), v (n), v (n-1)); v (n) = h (u (n-1), u (n-2), v (n), v (n-1)) ...
Mein Vorschlag wäre also, dass Sie einfache (in ihrem Ausdruck) Standardrekursions- "Probleme" finden und versuchen, sie in der Sprache Ihrer Wahl zu implementieren. Übung wird Ihnen helfen, zu lernen, wie Sie diese "Probleme" denken, lesen und ausdrücken. Beachten Sie, dass einige dieser Probleme häufig durch Iteration ausgedrückt werden können, eine Rekursion jedoch möglicherweise eine elegantere Methode zur Lösung darstellt. Eine davon ist die Berechnung von Fakultätszahlen.
Grafische "Probleme", die ich finde, erleichtern das Erkennen. Schauen Sie sich also Kochs Flocken, Fibonacci, die Drachenkurve und Fraktale im Allgemeinen an. Schauen Sie sich aber auch den Schnell-Sortier-Algorithmus an ...
Sie müssen ein paar Programme zum Absturz bringen (Endlosschleifen, versuchsweise Verwendung unendlicher Ressourcen) und die Endbedingungen falsch handhaben (um unerwartete Ergebnisse zu erzielen), bevor Sie sich mit all dem befassen. Und selbst wenn Sie es bekommen, werden Sie diese Fehler immer noch machen, nur seltener.
quelle
Struktur und Interpretation von Computerprogrammen
Es ist das Buch, das zum Lernen, nicht nur zur Rekursion, sondern allgemein zum Programmieren an verschiedenen Universitäten verwendet wird. Es ist eines dieser grundlegenden Bücher, die mehr Informationen liefern, je mehr Erfahrung Sie sammeln und je mehr Sie lesen.
quelle
So sehr ich SICP und Gödel, Escher, Bach: ein ewiges goldenes Geflecht mag , macht Touretzkys LISP: Eine sanfte Einführung in die symbolische Berechnung auch einen guten Job bei der Einführung der Rekursion.
Das Grundkonzept lautet wie folgt: Zuerst müssen Sie wissen, wann Ihre rekursive Funktion beendet ist, damit ein Ergebnis zurückgegeben werden kann. Dann müssen Sie wissen, wie Sie den unvollendeten Fall auf etwas reduzieren, auf das Sie zurückgreifen können. Für das traditionelle Beispiel der Fakultät (N) sind Sie fertig, wenn N <= 1 ist, und der unfertige Fall ist N * Fakultät (N-1).
Für ein viel hässlicheres Beispiel gibt es Ackermanns Funktion A (m, n).
quelle
Ich schlage vor, mit einigen funktionalen ML-Sprachen wie OCaml oder Haskell herumzuspielen. Ich fand, dass die Syntax der Mustererkennung mir wirklich half, auch relativ komplizierte rekursive Funktionen zu verstehen, sicherlich viel besser als die von Scheme
if
undcond
Anweisungen. (Ich habe Haskell und Schema gleichzeitig gelernt.)Hier ist ein triviales Beispiel für Kontrast:
und mit Pattern Matching:
Dieses Beispiel wird dem Unterschied nicht wirklich gerecht - ich hatte nie Probleme mit einer der beiden Versionen der Funktion. Es soll nur veranschaulichen, wie die beiden Optionen aussehen. Sobald Sie mit Listen und Bäumen zu komplexeren Funktionen gelangen, wird der Unterschied noch deutlicher.
Ich empfehle Haskell besonders, weil es eine einfache Sprache mit sehr guter Syntax ist. Es ist auch viel einfacher, mit fortgeschritteneren Ideen wie Corecursion zu arbeiten :
(Sie werden den obigen Code erst verstehen, wenn Sie ein wenig mit Haskell spielen, aber seien Sie versichert, dass er im Grunde magisch ist: P.) Natürlich können Sie dasselbe mit Streams in Scheme tun, aber es ist in Haskell viel natürlicher.
quelle
Es ist vergriffen, aber wenn Sie es finden können, handelt es sich bei "Recursive Algorithms" von Richard Lorentz nur um eine Rekursion. Es behandelt die Grundlagen der Rekursion sowie spezifische rekursive Algorithmen.
Die Beispiele sind in Pascal, aber nicht so groß, dass die Wahl der Sprache lästig ist.
quelle