如何使用Clojure生成Fibonacci序列?

时间:2011-04-16 19:01:02

标签: clojure fibonacci

(ns src.helloworld)

(defn fibonacci[a b] (println a b (fibonacci (+ b 1) a + b)))

(fibonacci 0 1)

我是功能编程的新手,并决定开始学习Clojure,因为它与C#的非常不同。我想拓宽视野。

这是我得到的错误:

Clojure 1.2.0
java.lang.IllegalArgumentException:
Wrong number of args (4) passed to:
helloworld$fibonacci
(helloworld.clj:0) 1:1 user=>
#<Namespace src.helloworld> 1:2 src.helloworld=>

数学问题从来都不是我的强项,而且我从来没有做过任何操纵过这样的数字的事情,所以我希望你能提供任何指导。

请不要给我整个解决方案。

最好是我想要一些好的提示,也许是它应该是什么样子的骨架。

5 个答案:

答案 0 :(得分:4)

(fibonacci (+ b 1) a + b)

在这里,您使用四个参数调用函数fibonacci(+ b 1)的结果,变量a的值,函数+和值{变量b。由于fibonacci被定义为只接受两个参数,因此您会收到错误。

修复此问题后,您将收到堆栈溢出错误而不会看到任何输出。这是因为您将fibonacci的递归调用作为println的参数。因此它会在执行println之前尝试执行递归调用。由于递归是无限的,因此对println的调用永远不会发生。你应该做的是先打印数字,然后递归调用fibonacci

一旦你这样做,程序将打印很多数字,但堆栈最终仍会溢出。这是因为clojure不会优化尾调用,因此即使使用尾递归,无限递归也会导致堆栈溢出。为了防止这种情况,请使用recur表单而不是正常的递归。

除了这些要点之外,当您错误地实施Fibonacci序列时,您的程序将打印错误的数字。

答案 1 :(得分:3)

这是一个关于你为什么会遇到错误的提示。您将以下四个参数传递给fibonacci

  • (+ b 1)
  • a
  • +
  • b

那仍然不会给你一个工作函数,这里有一个暗示:什么会导致代码停止执行并向用户返回一个值?

答案 2 :(得分:1)

其他答案向您解释函数调用中的错误。修复之后你应该考虑使用loop / recur来进行尾调用优化,因此不会在每次递归调用时使用堆栈。如果没有给你完整的东西,那么很难给出一个例子: - /这是另一个线程,他们在clojure中使用递归计算一个阶乘:Factorial

答案 3 :(得分:1)

当我通过一些类似的代码katas学习时,我发现这个网站非常有用。 Coding Kata。它们具有作为黄带kata的纤维序列。他们还提供了多种语言的人们发布的解决方案(Clojure就是其中之一)。这样,您可以将您的答案与其他人进行比较,看看您是否能够获得任何提示或更好的做事方式。

答案 4 :(得分:0)

当你完成后,你可能希望在Stu Halloway的 Programming Clojure 中看一下Christophe Grand的Fibonacci解决方案。这是我见过的最优雅的解决方案。它是在第1版的第137页(因为我听说有第2版即将推出)。