5

私は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 では、次の 1 つのライナーを記述できます。

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

Haskell ソリューションは無限のシーケンス (遅延...) を提供することに注意してください。Clojure が熱心な解決策と怠惰な解決策の両方である場合 (n の長さのリストを取得する場合でも)、両方を知りたいです。

更新:私が得た別の解決策は、逆のリストを生成しませんが、スタックを使用して生成します:

(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))
4

2 に答える 2

0

これはシーケンス全体を生成しませんが、反復アルゴリズムで n 番目のフィボナッチ数を見つけるのに適しています。私は clojure を学んでいるだけなので、このアプローチについて人々がどう思うか、何か問題があるかどうかに興味があります。きれいではありませんし、賢くもありませんが、機能しているようです。

(defn fib [n]
  (if (< n 2)
    n
    (loop [i 1
           lst 0
           nxt 1]
      (if (>= i n)
        nxt
        (recur (inc i) nxt (+' lst nxt))))))
于 2019-10-07T05:45:14.413 に答える