Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/clojure/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何在clojure中为变量重新赋值_Clojure_Fibonacci - Fatal编程技术网

如何在clojure中为变量重新赋值

如何在clojure中为变量重新赋值,clojure,fibonacci,Clojure,Fibonacci,我正在为斐波那契级数做这个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) 我不知道如何重新

我正在为斐波那契级数做这个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)

我不知道如何重新分配变量
a
b
c
。此外,请建议程序中需要的任何更正。

如评论中所述,请使用您通常使用的命令式语言 通过改变变量的值来解决这个问题。但从功能上来说 像Clojure这样的语言的重点是不变性、函数调用和 递归。而你可以找到一个解决方案 , ,或诸如此类,这不是风格 您应该在Clojure中编程(至少对于此类问题)

因此,迭代计算斐波那契数的函数可以 像这样(另见 ):

fib iter
是一个局部函数,递归调用自身(通过 ).但如文所述 :

由于Clojure使用Java调用约定,因此它不能也不会使 同样的尾部调用优化保证。相反,它提供了重现性 特殊运算符,通过重新绑定和 跳转到最近的封闭循环或功能框架

因此,您可以用 得到 迭代过程,或者您可以使用 这稍微简化了代码:

(defn fibonacci
  [n]
  (loop [a 1
         b 0
         count n]
    (if (= count 0)
      b
      (recur (+ a b) a (- count 1)))))

首先,让我们让您的代码正常工作。定义函数的第一个
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)))
不是你想要的。问题在于
(a b c)
前面的引号,它返回列表中未计算的元素。我们必须取消报价,但我们不希望
a
被视为操作员。因此,请输入
列表

(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)))
我们有数字,但不是我们想要的。问题在于,第一个
(def c(+a b))
清除了唯一的非零值。我们应该从
1
b
开始,暂时使用
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)))
万岁

但是我们可以看到
b
c
是相同的,只需预测下一个
a

还有一个更大的问题。使用可变变量不是Clojure的方法。函数打印其计算结果也不是惯用做法:更好地将结果发展为一个序列,这样我们就可以随心所欲了

我们可以这样定义整个斐波那契序列:

(defn fibonacci []
  (map second
       (iterate
         (fn [[a b]] [b (+ a b)])
         [0 1])))
只要开发出我们想要的:

   (take 10 (fibonacci))

=> (1 1 2 3 5 8 13 21 34 55)

几点提示:定义函数应该由defn完成,而不是def。分配局部变量是由let而不是def完成的。只在一个函数中使用的原子通常意味着您的方法是必需的,而不是功能性的。我建议从一些4clojure.com练习开始,这可以建立你的功能性思维。看起来你是带着一种命令式思维进入的。除了@NielsK的建议之外,也许你可以看看《勇敢与真实》免费书中的
Clojure,或者《从头开始》系列中的
Clojure。这需要一些时间来适应,如果你没有已经“进入”Clojure的同事或朋友为你指路,那么你最好的选择就是跟随任何一本关于Clojure的书。上面提到的都很好。@santossahoo很好!从你的代码到我的代码有很大的飞跃:你必须学习和,这使我的计算保持与你的相同的形状。顺便说一句,我做了一些小的修正。我注意到了。再次感谢你
> (fibonacci)

(0 0 0)
(0 0 0)
...
(0 0 0)
=> nil
(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)))
> (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
(defn fibonacci []
  (map second
       (iterate
         (fn [[a b]] [b (+ a b)])
         [0 1])))
   (take 10 (fibonacci))

=> (1 1 2 3 5 8 13 21 34 55)