Tail Rekursive Levenshtein Entfernung

7

Ich habe Levenshtein Distance in einer ziemlich normalen Weise in F # als Übung implementiert.

%Vor%

Ich sehe jedoch keine direkte Möglichkeit, den Aufruf von List.min so zu konvertieren, dass er rekursiv ist. Wir machen nicht einfach einige zusätzliche, unabhängige Berechnungen nach dem rekursiven Aufruf; Stattdessen wählen wir das Ergebnis mehrerer rekursiver Aufrufe.

Gibt es eine Möglichkeit, dies elegant zu konvertieren, um rekursiv zu sein?

(Ich kann das +1 einfach so umwandeln, dass es rekursiv ist)

    
jameszhao00 13.02.2013, 18:00
quelle

3 Antworten

12

Wenn Sie Code in ein tail-rekursives Formular umwandeln möchten, haben Sie im Allgemeinen zwei Möglichkeiten:

  • Wenn Ihre rekursive Funktion sich nur einmal nennt , können Sie accumulator parameter verwenden.
  • Wenn es sich mehrmals selbst aufruft, müssen Sie fortsetzungen verwenden

Wie Jeffrey sagt, sieht der Fortsetzungsmodus etwas hässlich aus, weil Sie alle Funktionen so umformen müssen, dass sie eine andere Funktion übernehmen und das Ergebnis zurückgeben, indem Sie sie aufrufen. Sie können dies jedoch etwas schöner gestalten, da Fortsetzungen Monaden sind und Sie Berechnungsausdrücke verwenden können.

Wenn Sie den folgenden Berechnungsgenerator definieren:

%Vor%

Dann können Sie die Lösung von @gradbot wie folgt umschreiben (und die explizite Konstruktion von Lambda-Funktionen loswerden):

%Vor%     
Tomas Petricek 13.02.2013, 22:20
quelle
7

Wenn Sie das Minimum für eine Reihe von rekursiven Aufrufen verwenden möchten, können Sie diesen Tail nicht rekursiv ausführen. Sie müssen die Operation min nach allen Aufrufen ausführen.

Sie können jede Berechnung so konvertieren, dass sie Tail-Aufrufe verwendet, indem Sie in den Fortsetzungsmodus umwandeln.

Die Art der Fortsetzung des Passierens sieht (für mich) oft kompliziert aus, aber ich vermute, wenn man sich erst einmal daran gewöhnt hat, ist das ziemlich einfach.

    
Jeffrey Scofield 13.02.2013 18:21
quelle
4

Die Grundidee des Fortfahrens besteht darin, dass Sie zukünftige Arbeiten in einer Funktion "verstecken".

%Vor%

Ausgabe

%Vor%     
gradbot 13.02.2013 21:30
quelle