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

数学问题从来都不是我的强项,我也从来没有真正做过像这样操纵数字的东西,所以我希望你能给我任何指导。

请不要给我完整的解决方案。

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

4

5 回答 5

4
(fibonacci (+ b 1) a + b)

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

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

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

除了这些点之外,当您错误地执行斐波那契数列时,您的程序将打印错误的数字。

于 2011-04-16T19:08:17.063 回答
3

这是有关您遇到错误的原因的提示。您将以下四个参数传递给fibonacci

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

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

于 2011-04-16T19:09:26.060 回答
1

其他答案向您解释了函数调用中的错误。修复后,您应该考虑使用循环/递归,这将进行尾调用优化,因此不为每个递归调用使用堆栈。但是,如果不给你整个事情,就很难给出一个例子:-/ 这是另一个线程,他们在 clojure 中使用递归计算阶乘:Factorial

于 2011-04-16T19:14:27.030 回答
1

当我通过一些类似的代码 katas 来学习时,我发现这个站点非常有帮助。 编码卡塔。他们有 fib 序列作为黄带 kata。他们还发布了人们以多种语言发布的解决方案(Clojure 就是其中之一)。这样,您可以将您的答案与其他人进行比较,看看您是否可以找到任何提示或更好的做事方式。

于 2011-04-16T20:05:06.643 回答
0

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

于 2011-05-26T05:44:25.400 回答