2013-07-08 121 views
3

我正在學習Clojure。相當基本的任務是生成斐波那契數列。我最終的解決方案勢在必行的非常複印件(和列表相反,呵呵):Clojure中的斐波那契數字

(defn n-fib [n] 
    (if (= n 1) '(1) 
    (loop [i 2 l '(1 1)] 
    (if (= i n) 
     l 
     (recur (inc i) (cons (+ (fst l) (snd l)) l)))))) 

什麼更好的辦法是,更多的功能,簡潔的?懶序列?如何使用它們?例如,在Haskell使用懶惰我可以寫一個內膽:

fib = 1 : 1 : zipWith + (tail fib) 

注意,哈斯克爾解決方案提供了無限的序列(懶惰......)。如果Clojure既渴望又懶惰的解決方案可以(甚至像獲得長度列表)我想知道這兩個。

更新:另一種解決方案我的產量沒有扭轉名單,但是它使用堆棧生成它:

(defn n-fib [n] 
    (defn gen [i a b] 
    (if (= i 0) 
     () 
     (cons (+ a b) (gen (dec i) b (+ a b))))) 
    (gen n 0 1)) 
+1

您可以使用向量表示而不是列表。最後一個帶有生成器的解決方案,您應該能夠使用stream-cons來避免使用堆棧。流是一對,其中第一項是一個值,第二項是用於計算其餘值的延遲表達式。 – WorBlux

+1

在Clojure中,不應該在函數內使用'def' /'defn';特別是如果你這樣做,全球變量是創建的,而不是當地人。爲了介紹當地人,使用'let'或'letfn'。 –

+1

這是着名的SICP書中無限流(=流lazy-seq)部分中的第一個例子之一。強烈建議閱讀,以掌握基本的懶惰seq概念http://mitpress.mit.edu/sicp/full-text/book/book-ZH-24.html#%_sec_3.5.2 –

回答

7

你可能想看看http://en.wikibooks.org/wiki/Clojure_Programming/Examples/Lazy_Fibonacci

相當於你的懶惰哈斯克爾的解決方案是這樣的

(def fib (lazy-cat [1 1] (map + (rest fib) fib))) 
+0

我發現幾乎在http:// clojuredocs .org/clojure_core/clojure.core/iterate和http://clojuredocs.org/clojure_core/clojure.core/lazy-seq。兩者都有斐波納契序列作爲樣本。 – demi