2016-10-18 145 views
1
#(take % 
    (map first 
    (iterate (fn [[i1 i2]] 
       [i2 (+ i1 i2)]) 
      [1 1]))) 

這是在clojure中生成fib seq的函數。 我不理解這一部分:Clojure斐波納契

(fn [[i1 i2]] 
      [i2 (+ i1 i2)]) 
      [1 1]) 

從[I1 I2]至[12(+ I1 I2)]。 如何使這個序列不斷增長?在我看來,它始終是2個元素。 需要幫助。謝謝!

+0

雖然這個問題很與這個問題密切相關,我認爲它不是重複的,因爲它更具體。 –

+0

由於縮進不良,看起來很混亂。它看起來像內部函數的主體和'iterate'的第二個參數處於同一級別。 – Svante

+0

修復了格式 –

回答

3

功能

(fn [[i1 i2]] 
    [i2 (+ i1 i2)]) 

發生在序列中的一個步驟和懶序列產生該過程中的下一步。所以每個呼叫都會在序列中再增加一步。這是每個步驟都有兩個元素的中間解決方案。第一個元素是迄今爲止的答案,第二個元素提供足夠的上下文來產生下一步。因此輸出看起來像:

user> (take 5 
      (iterate (fn [[i1 i2]] 
         [i2 (+ i1 i2)]) 
        [1 1])) 
([1 1] [1 2] [2 3] [3 5] [5 8]) 

然後稍後階段需要這種全序列,並刪除多餘的信息,只留下從每一步的答案。

user> (map first 
      (take 5 
       (iterate (fn [[i1 i2]] 
          [i2 (+ i1 i2)]) 
          [1 1]))) 
(1 1 2 3 5) 

這是打破一個問題分解成可分部分,然後合成這些部分,以形成最終的答案有很大的應用。

1

傳遞給iterate功能是

(fn [[i1 i2]] 
    [i2 (+ i1 i2)]) 

所有功能並是產生給定的前一個序列中的下一個項(使用模式匹配來分配名稱i1和i2到的成員傳入的向量)。

iterate接受兩個參數,即生成序列中下一項的函數以及序列的起始值。函數iterate負責生成延遲序列。

對於一個更簡單的實施例(沒有模式匹配),則可以生成的正整數用

(iterate inc 0) 
0

你說得很對。功能...

(fn [[i1 i2]] [i2 (+ i1 i2)]) 

...確實會產生一對數字。例如,

((fn [[i1 i2]] [i2 (+ i1 i2)]) [6 19]) 

; [19 25] 

它的iterate它通過重複應用函數產生序列。這就產生了對的序列:

(iterate (fn [[i1 i2]] [i2 (+' i1 i2)]) [1 1]) 

;([1 1] [1 2] [2 3] [3 5] [5 8] [8 13] [13 21] ...) 

第一或這些對的第二元素形成斐波納契數列,根據 要開始。爲了得到前者,我們只是包裝上面的(map first ...)

(map first (iterate (fn [[i1 i2]] [i2 (+' i1 i2)]) [1 1])) 

;(1 1 2 3 5 8 13 21 ...) 

如果你熟悉->>線程宏,你可能會發現更容易閱讀的

(->> [1 1] 
    (iterate (fn [[i1 i2]] [i2 (+ i1 i2)])) 
    (map first)) 

;(1 1 2 3 5 8 13 21 ...)