Clojure中的斐波纳契数

时间:2013-07-08 02:28:36

标签: clojure functional-programming

我正在学习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) 

请注意,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))

2 个答案:

答案 0 :(得分:7)

您可能需要查看http://en.wikibooks.org/wiki/Clojure_Programming/Examples/Lazy_Fibonacci

与你的懒惰Haskell解决方案相当的是

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

答案 1 :(得分:0)

这不会生成整个序列,但是它善于使用迭代算法找到第n个斐波那契数。我只是在学习Clojure,所以我会对人们对这种方法的看法以及它是否存在问题感兴趣。它不漂亮,也不聪明,但似乎确实有效。

public static void signUser(User u) {
      if(!users.isEmpty()){
        for(User f: users) {
            if(u.name.equals(f.name)) {
                System.out.println("User already exists");
            }
            else {
                users.add(u);
                System.out.println("User signed");
            }
        }
      } else{
      users.add(u.name);
      }
     }