2017-10-30 1 views
2

Ich dachte, ich recur verstanden, aber die folgenden Nutzungs keinen Sinn machen:Wie wird hier rekurriert? [Clojure]

(fn gcd [a b] 
    (if (= b 0) 
     a 
     (recur b (rem a b)))) 

Die Funktion für zwei Zahlen die größten gemeinsamen Teiler abruft. Für 4 und 2 würde die Funktion 2.

Ich weiß, dass wiederkehrende Funktionen gebunden werden können, aber ich würde denken, dass "b" nur durch die Wiederholung ohne Änderung durchlaufen wird. Im Allgemeinen müssen Sie etwas wie a (inc b) eingeben, damit sich der Wert in der Schleife ändern kann.

Was fehlt mir?

Antwort

3

Die gcd-Funktion verwendet hier Euclidean algorithm, um den größten gemeinsamen Teiler von zwei Zahlen zu finden.

Die Funktion funktioniert und endet, weil die Argumentliste enthält, aber die Wiederholung wird für b, (rem a b) aufgerufen. Beachten Sie, dass der Platz von b hier geändert wird (vom zweiten zum ersten Platz).

Der Wert a wird geändert, weil der Wert b ihm zugewiesen ist. Außerdem wird der Wert von b geändert, weil (rem a b) ihm zugewiesen ist (also abnimmt). Daher nehmen beide Werte ab, wenn die Aufrufe wiederholt werden, und einer von ihnen erreicht schließlich 0 (was die Rekursion stoppt).

2
(fn gcd [a b] 
    (if (= b 0) a 
    (recur b (rem a b)))) 

Zum Beispiel nenne ich diese Funktion mit dem Argument a = 24, b = 16 Diese Funktion rekursiv so lange aufgerufen wird als b nicht Null ist.

(gcd 24 16) 
=> (gcd 16 8)) #_"because b=24 doesn't equal to zero and 8 is the reminder of 24/16" 
=> (gcd 8 0) #_"0 is the reminder of 16/8" 
=> 8 

Diese Berechnung stoppt, weil b Null erreicht.

2

Ja, Sie möchten die Werte in einem rekursiven Aufruf ändern, damit Ihr Test schließlich erfolgreich ist und Sie die Rekursion verlassen. Dieser Algorithmus führt genau das durch Senden des neuen ersten Parameters mit dem Wert des alten zweiten Parameters aus, und der neue zweite Parameter wird basierend auf den alten ersten und alten zweiten Parametern neu berechnet.

Versuchen Sie etwas wie (println "a:" a "b:" b) vor der if-Anweisung in der Funktion hinzuzufügen, und Sie sehen die Werte durchlaufen, wie es die Antwort sucht.