Rekursive Programmierung beherrschen
Ich habe Probleme beim denken/lösen das problem in Bezug auf die Rekursion. Ich wirklich zu schätzen, das Konzept und ich kann Sie verstehen, wie die Erstellung von Basis-Gehäuse, Ausgang-Gehäuse & die rekursiven Aufrufe etc. Ich kann bei der Lösung einfacher Probleme wie das schreiben einer Fakultät oder Summierung der zahlen in einem array. Das ist, wo mein denken aufhört. Konnte ich nicht wirklich anwenden, die Konzepte oder Lösungen, wenn das problem kompliziert. Zum Beispiel, Turm von Hanoi, kann ich zwar verstehen, das problem und die Lösung habe ich, auf meinem eigenen kann nicht mit einer Lösung. Es gilt auch für andere algorithmen wie quick sort/binary tree traversal als gut. Also meine Frage ist
- Was ist der beste Weg, um es zu meistern?
- Kann jeder jeden schlagen eine Liste von Fragen oder Probleme, die ich benutzen kann als übung der Praxis?
- Wird das lernen funktionale Sprache, die mir helfen, mit meinem Verständnis?
Bitte um Rat.
10! = 1 * 10! = 10 * 9!
, also beides, problem und Lösung sind von der form a * b!
. Die meisten Leute finden, Abstraktionen schwierig. Aber tatsächlich, es ist alles zu versuchen, die ähnlichkeiten finden sich in unterschiedlichen Situationen. Sie können sogar Praxis, dass Sie in Ihrem täglichen Leben (versuchen zu sehen, die ähnlichkeiten in zwei verschiedene Konzepte). InformationsquelleAutor der Frage Hunter | 2014-03-28
Du musst angemeldet sein, um einen Kommentar abzugeben.
Rekursion ist nur eine Art des Denkens, die nur als iterativer ist. Als wir Kinder waren in der Schule, wir waren nicht gelehrt zu denken, rekursiv, und da liegt das eigentliche problem. Sie brauchen, um aufzunehmen, dass die Art des Denkens in Ihrem arsenal, sobald Sie es tun, es wird für immer dort bleiben.
Besten Weg zum Meister:
Fand ich nützlich, um immer herauszufinden, die Basis Fällen zunächst vielleicht auf den ersten, Sie sind nicht die einfache, aber sobald Sie anfangen Bau der Rekursion auf der Oberseite der base-case werden Sie feststellen, Sie können es vereinfachen. Die Bedeutung der Ermittlung des base-case ist, dass du zuerst darauf konzentrieren, was gelöst werden muss in seiner einfachsten form (einfachere Fälle) und diese irgendwie zieht einen Fahrplan für die Zukunft-Algorithmus, zweite, stellen Sie sicher, dass der Algorithmus hält. Vielleicht kommt nicht das erwartete Ergebnis, aber wenigstens Stoppt, das ist immer ermutigend.
Auch immer helfen, herauszufinden, wie eine kleine Instanz eines Problems hilft Ihnen bei der Suche nach der Lösung eines größeren Instanz des Problems. Dieses ist zum Beispiel, wie können Sie die Projektmappe erstellen, für die Eingabe
n
nachdem bereits die Lösung der Eingangsn-1
.Lösen jedes problem, das Sie denken können rekursiv. Ja, die Türme von Hanoi ist nicht ein sehr gutes Beispiel, seine rekursive Lösungen ist ein sehr clevere Lösung. Versuchen einfacher Probleme, fast Elementare Probleme.
Liste der Probleme, die
Aber am wichtigsten ist, beginnen Sie mit einfachen Problemen. Fast alle Probleme haben eine rekursive Lösung. Mathematische Probleme sind groß, um in den Griff bekommen. Jedes mal, wenn Sie sehen, ein
for
Schleife oder einwhile
Schleife, schalten Sie diesen Algorithmus in der Rekursion.Programmiersprache
Funktionale Programmierung stützt sich stark auf Rekursion. Ich glaube nicht, dass sollte helfen viel, da Sie von Natur aus rekursiv und mühsam sein kann für Benutzer, die nicht verstehen, Rekursion sehr viel noch.
Verwenden Sie eine einfache Programmiersprache, die Sie am meisten vertraut, vorzugsweise eine, die nicht Ihren Geist beschäftigt viel mit Speicher ärgernisse und Zeiger. Python ist ein sehr guter Anfang meiner Meinung nach. Ist sehr einfach, stört Sie nicht mit der Eingabe oder komplizierte Datenstrukturen. Solange die Sprache hilft Ihnen, bleiben Sie konzentrierte sich nur auf Rekursion, es wird besser werden.
Einen letzten Rat, wenn Sie nicht finden können, eine Lösung für ein problem, suchen Sie im internet oder rufen Sie um Hilfe, verstehen, was es tut ganz bewegen und auf den anderen. Lassen Sie sich nicht, Sie umgehen Sie, weil das, was Sie zu tun versuchen ist aufzunehmen, dass die Art zu denken, um Ihren Kopf.
Zu master Rekursion, müssen Sie sich zunächst master Rekursion 🙂
Hoffe, das hilft!
InformationsquelleAutor der Antwort Paulo Bu
Mein Ratschlag: Vertrauen, dass die rekursive Funktion "macht den job", d.h. es erfüllt die Spezifikation. Und zu wissen, dass, können Sie bauen eine Funktion, löst ein größeres problem, während immer noch die Erfüllung der Spezifikation.
Wie lösen Sie die Türme von Hanoi-problem ? Angenommen, es gibt eine Funktion Hanoi(N) zu verschieben, können Sie einen Stapel von N Scheiben ohne Verstoß gegen die Regeln. Mit dieser Funktion, die Sie leicht umsetzen Hanoi'(N+1): führen Hanoi(N), bewegen Sie den nächsten Datenträger, und führen Hanoi(N) wieder.
Wenn Hanoi(N) arbeitet, dann Hanoi'(N+1) funktioniert so gut, ohne Verstoß gegen die Regeln. Zum Abschluss der argument, müssen Sie sicherstellen, dass die rekursiven Aufrufe werden beendet. In diesem Fall, wenn Sie lösen können, die von Hanoi(1) nicht rekursiv (das ist trivial), sind Sie fertig.
Dieser Ansatz, Sie haben keine sorgen zu machen darüber, wie die Dinge tatsächlich auftreten, Sie werden garantiert, dass es funktioniert. (Vorausgesetzt, Sie bewegen sich, um kleinere und kleinere Instanzen des Problems.)
Anderes Beispiel: rekursive Traversierung eines binären Baum. Übernehmen die Funktion
Visit(root)
macht den job. Dannif left -> Visit(left); if right -> Visit(right); print root
wird die Arbeit machen ! Da der erste Aufruf wird gedruckt, der linke Teilbaum (nicht sich sorgen, wie Sie) und die zweite den rechten Teilbaum (keine Sorge, wie), und das root-gedruckt werden zu können.Im letzteren Fall ist die Kündigung durch die Tatsache gewährleistet, dass Sie Prozess kleiner und kleiner Teilbäume, nach unten zu Blättern.
Anderes Beispiel: Quicksort. Angenommen, Sie haben eine Funktion sortiert ein array in-place, lassen Sie Quicksort. Verwenden Sie es wie folgt: bewegen sich die kleinen Elemente, bevor Sie große Elemente, in-place, im Vergleich zu einem gut gewählten "pivot" - Wert (eigentlich jeden Wert aus dem array). Dann Sortieren Sie die kleinen Elemente mit Hilfe des Quicksort-Funktion, und die großen Elemente die gleiche Weise, und Sie sind fertig ! Keine Notwendigkeit zu Fragen, die genaue Reihenfolge der Partitionen, die stattfinden werden. Die Kündigung ist gewährleistet, wenn Sie vermeiden void subarrays.
Letztes Beispiel, Pascal ' s Triangle. Sie wissen, dass ein element ist die Summe der beiden über ihm, mit 1 Seiten. So mit geschlossenen Augen,
C(K, N)= 1 if K=0 or K=N, else C(K, N) = C(K-1, N-1) + C(K, N-1)
. Das ist es !InformationsquelleAutor der Antwort Yves Daoust
Studium einer funktionalen Sprache würde sicherlich helfen, Sie denken in die Rekursion. Ich würde empfehlen, entweder in Haskell oder Lisp (oder Clojure). Das schöne ist, Sie brauchen nicht zu bekommen, um die "harten bits" von diesen beiden Sprachen, bevor es zu der Rekursion. Um zu erfahren, über Rekursion, die Sie nicht müssen lernen, genug von diesen beiden Sprachen zu tun "echte" Programmierung.
Haskell pattern-matching-syntax bedeutet, dass die base-Fälle sind leicht zu sehen. In Haskell, die Fakultät sieht so aus:
... das ist genau äquivalent zu einer prozeduralen Sprache:
... aber mit weniger syntax zu verschleiern Konzept.
Vollständigkeit halber, hier der gleiche Algorithmus in Lisp:
Sollten Sie in der Lage, um zu sehen, gleichwertig, obwohl Sie zuerst alle Klammern neigen dazu, zu verschleiern, die Menschen Blick auf, was Los ist. Noch ein Lisp-Buch deckt eine Menge von rekursiven Techniken.
Darüber hinaus jedes Buch, das auf einer funktionalen Sprache wird Ihnen viele Beispiele für Rekursion. Sie beginnen mit algorithmen, die die Arbeit mit Listen:
.. die nutzt ein sehr häufiges Muster mit einer rekursiven Aufruf pro Funktion. (Eigentlich ein Muster so verbreitet, dass fast alle Sprachen, die abstrakte in eine library-Funktion genannt
map
)Dann werden Sie bewegen auf, um Funktionen, die Durchlaufen und Bäumen, durch einen rekursiven Aufruf für jeden Zweig aus einem Knoten.
Generell denke, dass Probleme wie diese:
... oder ...
So, zum Beispiel,
factorial(n)
ist einfach zu arbeiten, wenn Sie wissenfactorial(n-1)
, die schlägt vor, eine rekursive Lösung.Es stellt sich heraus, dass viele der Probleme gedacht werden kann, die Art und Weise:
...
...
Ebenso der Turm von Hanoi. Die Lösung ist einfach, wenn Sie es so:
Wir haben das problem einfach Aussehen durch skizzieren von über zwei scheinbar schwierigsten Schritte. Aber diese Schritte sind nur wieder das selbe problem, aber "kleinere".
Finden Sie es vielleicht nützlich, um manuell Schritt für Schritt durch einen rekursiven Algorithmus mit einem Stück Papier darstellen, auf dem Aufruf-stack, wie in dieser Antwort: Verständnis stack unwinding in die Rekursion (tree traversal)
Nachdem Sie haben mehr Komfort mit Rekursion, Kreis zurück und überlegen Sie, ob es die richtige Lösung für einen bestimmten Fall. Obwohl
factorial()
ist ein guter Weg, um zu zeigen, das Konzept der Rekursion, in die meisten Sprachen eine iterative Lösung effizienter ist. Informieren Sie sich über tail-Rekursion Optimierung, welche Sprachen Sie nicht, und warum.InformationsquelleAutor der Antwort slim
Rekursion ist ein bequemer Weg zur Umsetzung des Divide & Conquer-Paradigma: wenn Sie Sie brauchen, die zur Lösung eines bestimmten Problems, einer leistungsstarken Lösung ist, es zu brechen in Probleme von der gleichen Art, aber mit einer kleineren Größe. Durch die Wiederholung dieses Prozesses, werden Sie am Ende der Arbeit auf Probleme so klein sind, dass Sie können leicht gelöst werden durch eine andere Methode.
Die Frage, die Sie haben, um sich Fragen, "kann ich lösen dieses problem durch die Lösung teilen ?". Wenn die Antwort positiv ist, wenden Sie das bekannte Schema:
aufteilen des Problems in Teilprobleme rekursiv, bis die Größe ist klein,
lösen Sie die Teilprobleme, die durch eine direkte Methode,
Zusammenführen der Lösungen in der umgekehrten Reihenfolge.
Hinweis, dass die Spaltung kann in zwei Teile oder mehr, und können diese ausgeglichen werden oder nicht.
Zum Beispiel: kann ich ein array Sortieren von zahlen, die von der Durchführung teilweise sortiert ?
Antwort 1: ja, wenn ich das Letzte element aus und Sortieren den rest, ich kann irgendwie die ganze Palette durch einfügen, die das Letzte element an der richtigen Stelle. Dies ist insertion sort.
Antwort 2: ja, wenn ich finde das größte element und verschieben Sie es bis zum Ende, ich kann irgendwie die ganze Palette durch Sortieren der verbleibenden Elemente. Dies ist die Auswahl Sortieren.
Antwort 3: ja, wenn ich irgendwie zwei Hälften des Arrays, ich kann irgendwie die ganze Palette durch Zusammenlegung der beiden Sequenzen, die mit einem Hilfs-array für die Bewegungen. Dies ist merge-sort.
Antwort 4: ja, wenn ich die partition dem array mit einer pivot, ich kann irgendwie die ganze Palette durch Sortieren der beiden Teile. Dies ist quick sort.
In all diesen Fällen, die Sie lösen das problem durch Lösung der Teilprobleme der gleichen Art und das hinzufügen von etwas Kleber.
InformationsquelleAutor der Antwort Yves Daoust
Rekursion ist schwer, weil es ist eine andere Art des Denkens, eine, wir wurden nie eingeführt, als wir jünger waren.
aus, was Sie sagen, Sie haben bereits das Konzept alles, was Sie wirklich brauchen, ist nur um der Praxis mehr. eine funktionale Sprache, die definitiv helfen würde; Sie werden gezwungen sein, zu denken, über Ihre Probleme rekursiv und bevor Sie es wissen Rekursion scheinen sehr Natürliche
gibt es Tonnen von übungen, die Sie tun können, bezogen auf die Rekursion, Bedenken Sie, dass alles, was man mit einer Schleife getan werden kann rekursiv als gut.
sehen diese Antwort für einen tollen details über Referenzen und übung probelms
InformationsquelleAutor der Antwort Mhd.Tahawi
Für komplexe Probleme zu lösen, empfehle ich tun, das problem für kleine Größen problem und sehen, welche Arten von Muster, die Sie finden. Zum Beispiel, in den Türmen von Hanoi starten Sie mit einer problem-Größe von eins, dann zwei, dann drei, usw. An einem gewissen Punkt, werden Sie wahrscheinlich beginnen, um zu sehen, ein Muster, und Sie werden erkennen, dass einiges von dem, was Sie tun, ist genau das, was Sie zu tun hatten, auf die kleineren Probleme, oder, dass es ähnlich genug, dass Sie können verwenden die gleiche Technik wie zuvor, jedoch mit einigen Variationen.
Ging ich einfach durch die Türme von Hanoi problem mich und studierte mein eigenes denken. Ich begann mit einem problem der Größe:
Nun für zwei.
Nun für drei.
Beginnen die Dinge ein wenig interessanter. Die Lösung ist nicht so offensichtlich. Allerdings habe ich herausgefunden, wie bewegen Sie zwei Scheiben von einer Stange zur anderen, so dass, wenn ich könnte schieben Sie zwei Scheiben von Stange A nach Stange B, dann bewegen sich eine Scheibe von Stange A nach Stange C, und dann zwei Scheiben von Stange B nach Stange C, hätte ich es getan!
Meine Logik für den Fall von zwei Festplatten die Arbeit, außer dass die Heringe sind unterschiedlich. Wenn wir die Logik in eine Funktion, und stellen Sie die Parameter für die Heringe, dann können wir wieder die Logik.
Die Logik ist dann:
Ich kann machen dies einfacher durch eine Funktion move1 auch:
Nun meine move2-Funktion können Sie
Ok, was ist mit vier?
Scheint, wie ich kann, anwenden der gleichen Logik. Ich brauche, um drei Scheiben von Stange A nach Stange B, dann von A nach C, dann drei von B nach C. ich gelöst, bewegt die drei schon, aber mit der falschen Wirbel, so werde ich verallgemeinern:
Cool! Und warten, move3 und move2 sind ziemlich ähnlich wie jetzt, und das macht Sinn. Für jede Größe problem, das wir bewegen können, alle, aber einer der Festplatten zu peg B, dann bewegen sich eine Scheibe von A nach C, dann bewegen sich alle Datenträger auf peg-B-peg C. Also unsere Funktion verschieben können, nehmen Sie einfach die Anzahl der Festplatten, die als parameter:
Das sieht wirklich eng, aber es funktioniert nicht in dem Fall, wo n==1, weil wir uns am Ende den Aufruf move(0,...). Also müssen wir, damit umzugehen:
Ausgezeichnet! Was zu einem problem der Größe von fünf? Wir rufen move(5,'A','C','B'). Sieht aus wie jedes problem die Größe ist die gleiche Sache, also unsere main-Funktion ist einfach:
, und wir sind fertig!
InformationsquelleAutor der Antwort Vaughn Cato