Recursion clojure中的函数递归

Recursion clojure中的函数递归,recursion,clojure,Recursion,Clojure,我在处理clojure中的递归,我真的不太明白。 我制作了一个小程序,从中提取,试图找到可以被1到20的所有数字所除的smalles数。这是我写的代码,但肯定有什么我错过了,因为它不工作。 你能帮我一下吗?谢谢 (defn smallest [nume index] (while(not ( = index 0)) (do (cond (zero?(mod nume index))(let [dec' index] (smallest nume i

我在处理clojure中的递归,我真的不太明白。 我制作了一个小程序,从中提取,试图找到可以被1到20的所有数字所除的smalles数。这是我写的代码,但肯定有什么我错过了,因为它不工作。 你能帮我一下吗?谢谢

(defn smallest [nume index]
(while(not ( = index 0))
    (do
        (cond
            (zero?(mod nume index))(let [dec' index] (smallest nume index))
            :else (let [inc' nume] (smallest nume index))))))
编辑: 看起来是更好的
循环/重复
,所以我尝试了:

(loop [nume 20
            index 20]
        (if (= index 0)
        (println nume)
        (if (zero?(mod nume index))
                (recur nume (dec index))
                (recur (inc nume) 20)))))
工作。如果您对结果感到好奇-->232792560

不会做您认为它会做的事情

在clojure中,一切(好的,几乎)都是不可变的,这意味着如果
index
为0,那么在相同的上下文中它将始终为0。因此,循环直到它为1是没有意义的

有很多方法可以实现你想要做的事情,第一个,也是对新手来说最琐碎的(我想!),就是理解。例如:

(loop [counter 0] 
  (when (< counter 10) 
    (println counter)
    (recur (inc counter))))
(循环[计数器0]
(当(<计数器10)
(打印计数器)
(重复(包括计数器)))
在这里,
计数器
被定义为0,它不会以通常的方式更改。当您点击
recur
时,您将一个新值提交到一个全新的迭代中,该迭代从
循环开始,此时
计数器的增量将绑定到1

Edit:但是请注意,此示例将始终返回
nil
。它仅用于
println
的副作用。为什么它返回
nil
?因为在上一次迭代中,
when
子句将返回
nil
。如果您想返回其他内容,您可能应该使用
If
并指定您希望在最后一次迭代中返回的内容

你应该多读一点关于这个范例的内容,也许做一些练习来更好地理解它。一旦你这样做了,你用这种方式思考就会变得简单得多,并且这种方式的巨大好处将开始显现


祝你好运

下面是一个蛮力实现,测试代码中的所有数字是否可以除以1到10(请注意(范围11))的条件:

(first 
  (filter #(second %) 
          (map (fn[x] [x (every? identity 
                                  (map #(=  0 (mod x %)) 
                                  (range 2 11)))]) 
               (range 1 Integer/MAX_VALUE))))
它的输出是

[2520 true]
不幸的是,对于更大的数字来说,这不是一个好方法。在我的Macbook上等待几分钟后,使用(range 1 21)它不会结束。让我们试试这个:

user=> (defn gcd [a b] (if (zero? b) a (recur b (mod a b))))
#'user/gcd
user=> (reduce (fn[acc n] (if (not= 0 (mod acc n)) (* acc (/ n (gcd n acc))) acc)) 1 (range 1 11))
2520    
user=> (reduce (fn[acc n] (if (not= 0 (mod acc n)) (* acc (/ n (gcd n acc))) acc)) 1 (range 1 21))
232792560

投资于理解循环/重现、不变性和标准库序列转换函数-
,而
是一种强制性循环构造,根据我的经验,一年中使用的循环从未超过一次或两次。看来你是在瞎猜。。例如,您认为
(索引20)
有什么作用?另外,在
recur
中,值的顺序很重要,我不确定您是否在做您认为自己在做的事情。我只是编辑了关于顺序的问题。我对
(索引20)
的意思是再次将索引设置为20@shlomi@Capie,所以这不是它所做的。实际上,它会抛出一个错误,因为
索引
不是一个函数,您正试图将20应用于函数
索引
。如果希望将
索引保持为20,只需执行
(recur(inc nume)20)
。此注释也适用于
(nume)
,您正在尝试调用编号:)。我更新了我的答案,看看这是否有帮助。@shlomi帮了大忙。它起作用了。谢谢你,伙计。
#(第二个%
第二个
:)完全相同