我正在为斐波那契数列做这个 Clojure 程序。
(def fibonacci []
(def a 0)
(def b 0)
(def c 1)
(def n (atom 0))
(while (<= @n 10)
(do
(def c (+ a b))
(def a b)
(def b c)
(println '(a b c))
)(swap! n inc)))
(fibonacci)
Run Code Online (Sandbox Code Playgroud)
我收到此错误:
CompilerException java.lang.RuntimeException: Too many arguments to def, compiling:(C:\Users\user\AppData\Local\Temp\form-init4960759414983563364.clj:1:1)
CompilerException java.lang.RuntimeException: Unable to resolve symbol: fibonacci in this context, compiling:(C:\Users\user\AppData\Local\Temp\form-init4960759414983563364.clj:13:1)
Run Code Online (Sandbox Code Playgroud)
我不知道如何重新分配变量a,b和c. 并且还请建议程序中需要的任何更正。
首先,让您的代码正常工作。第一个def,定义一个函数,应该是defn:
(defn fibonacci []
(def a 0)
(def b 0)
(def c 1)
(def n (atom 0))
(while (<= @n 10)
(do
(def c (+ a b))
(def a b)
(def b c)
(println '(a b c))
)(swap! n inc)))
Run Code Online (Sandbox Code Playgroud)
它编译。让我们试试看:
> (fibonacci)
(a b c)
(a b c)
...
(a b c)
=> nil
Run Code Online (Sandbox Code Playgroud)
不是你想要的。麻烦在于 前面的引用(a b c),它返回未计算的列表元素。我们必须取消报价,但我们不想a被视为操作员。所以输入list:
(defn fibonacci []
(def a 0)
(def b 0)
(def c 1)
(def n (atom 0))
(while (<= @n 10)
(do
(def c (+ a b))
(def a b)
(def b c)
(println (list a b c))
)(swap! n inc)))
Run Code Online (Sandbox Code Playgroud)
让我们运行它:
> (fibonacci)
(0 0 0)
(0 0 0)
...
(0 0 0)
=> nil
Run Code Online (Sandbox Code Playgroud)
好吧,我们得到了数字,尽管不是我们想要的。问题是第一个(def c (+ a b))清除了唯一的非零值。我们应该从bat开始,暂时1使用c:
(defn fibonacci []
(def a 0)
(def b 1)
(def n (atom 0))
(while (<= @n 10)
(do
(def c (+ a b))
(def a b)
(def b c)
(println (list a b c))
)(swap! n inc)))
Run Code Online (Sandbox Code Playgroud)
现在 ...
> (fibonacci)
(1 1 1)
(1 2 2)
(2 3 3)
(3 5 5)
(5 8 8)
(8 13 13)
(13 21 21)
(21 34 34)
(34 55 55)
(55 89 89)
(89 144 144)
=> nil
Run Code Online (Sandbox Code Playgroud)
欢呼!
但是我们可以看到b和c是一样的,只是预测下一个a。
有一个更大的问题。使用可变变量不是 Clojure 的方式。函数打印它计算的内容也不是惯用的:更好地将结果开发为一个序列,我们可以用它做我们喜欢的事情。
我们可以这样定义整个斐波那契数列:
(defn fibonacci []
(map second
(iterate
(fn [[a b]] [b (+ a b)])
[0 1])))
Run Code Online (Sandbox Code Playgroud)
并且随心所欲地开发:
(take 10 (fibonacci))
=> (1 1 2 3 5 8 13 21 34 55)
Run Code Online (Sandbox Code Playgroud)