2011-12-21 17 views
7

Il clojure document dà i seguenti esempi:In clojure, come costruire la sequenza pigro usando algoritmo iterativo

(take 10 (iterate (partial + 2) 0)) 

(def powers-of-two (iterate (partial * 2) 1)) 
(take 10 powers-of-two) 

(def fib (map first (iterate (fn [[a b]] [b (+ a b)]) [1 1]))) 
(take 10 fib) 

qualcuno può spiegare la sintassi di algoritmo iterativo di clojure in dettaglio? Sono molto confuso con tutto l'uso. Perché due parentesi ci sono in (fn [[a b]] [b (+ a b)])?

Un altro esempio può essere trovato here:

(defn iter [[x y]] 
    (vector y (+ x y))) 

(nth (iterate iter [0 1]) 10000) 

risposta

15

iterate prende una funzione f e un valore iniziale x e produce una sequenza artificiale. Il primo elemento nel seq è x. Ogni elemento successivo viene calcolato chiamando lo f con l'elemento precedente.

Esempio 1:

(iterate (partial + 2) 0) 

Questo genera una sequenza, a partire da 0, dove ogni elemento è l'elemento precedente con 2 aggiunto ad esso. Cioè .:

0 
(+ 2 0) ; => 2 
(+ 2 2) ; => 4 
(+ 2 4) ; => 6 
; etc 

Ogni elemento della seq viene passata (partial + 2) quando si genera il seguente elemento.

Esempio 2:

(iterate (partial * 2) 1) 

Questo genera una sequenza, a partire da 1, in cui ogni elemento è l'elemento precedente moltiplicato per 2. Ie:

1 
(* 2 1) ; => 2 
(* 2 2) ; => 4 
(* 2 4) ; => 8 
(* 2 8) ; => 16 
; etc 

Nuovamente, si può vedere come ogni elemento si nutre della generazione del prossimo.

Esempio 3:

(iterate (fn [[a b]] [b (+ a b)]) [1 1]) 

Innanzitutto, (fn [[a b]] ...) è un modo per destructure un valore in parti. In questo caso, la funzione accetta un vettore a due elementi e lo decomprime nelle variabili locali a e b.

La funzione restituisce un vettore a due elementi contenente b e la somma di a e b (cioè il secondo valore della coppia precedente e la somma di entrambi i valori della coppia precedente).

Con questo in mente, questo iterate chiamata genera:

[1 1] 
[1 (+ 1 1)] ; => [1 2] 
[2 (+ 1 2)] ; => [2 3] 
[3 (+ 2 3)] ; => [3 5] 
[5 (+ 3 5)] ; => [5 8] 
; etc 

Poi (map first ...) afferra il primo valore in ogni coppia, che ti dà la sequenza di Fibonacci.

+0

+1 per il bel lavoro! –

+1

Grazie mille ~ Questo è fantastico! – lkahtz

Problemi correlati