Recursion 如何正确使用尾部递归?
我正试图从Recursion 如何正确使用尾部递归?,recursion,clojure,tail-recursion,Recursion,Clojure,Tail Recursion,我正试图从 要使用“重现”,请执行以下操作: (defn random-code [depth] (if (or (zero? depth) (zero? (rand-int 2))) (random-terminal) (let [f (random-function)] (cons f (repeatedly (get function-table f) #(random-code (de
要使用“重现”,请执行以下操作:
(defn random-code [depth]
(if (or (zero? depth)
(zero? (rand-int 2)))
(random-terminal)
(let [f (random-function)]
(cons f (repeatedly (get function-table f)
#(random-code (dec depth)))))))
问题是,我完全不知道怎么做。我唯一能想到的是这样的事情:
(defn random-code [depth]
(loop [d depth t 0 c []]
(if (or (zero? depth)
(zero? (rand-int 2)))
(if (= t 0)
(conj c random-terminal)
(recur depth (dec t) (conj c (random-terminal))))
(let [f (random-function)]
(if (= t 0)
(recur (dec depth) (function-table f) (conj c f))
(recur depth (dec t) (conj c f)))))))
这不是一段有效的代码,只是为了展示我试图解决它的方法,它只会变得越来越复杂。在clojure中是否有更好的方法将正常递归转换为尾部递归?这里有两个比较递归算法和循环递归的示例:
(defn fact-recursion [n]
(if (zero? n)
1
(* n (fact-recursion (dec n)))))
(defn fact-recur [n]
(loop [count n
result 1]
(if (pos? count)
(recur (dec count) (* result count))
result )))
(fact-recursion 5) => 120
(fact-recur 5) => 120
(defn rangy-recursive [n]
(if (pos? n)
(cons n (rangy-recursive (dec n)))
[n]))
(defn rangy-recur [n]
(loop [result []
count n]
(if (pos? count)
(recur (conj result count) (dec count))
result)))
(rangy-recursive 5) => (5 4 3 2 1 0)
(rangy-recur 5) => [5 4 3 2 1]
基本区别在于,对于
循环重复
,您需要第二个循环“变量”(此处命名为结果
)来累积算法的输出。对于普通递归,调用堆栈将累加中间结果。是的,解决方案很可能像代码一样复杂。您正在构建树而不是序列的原因。如果构建序列,通常会添加一个累加器参数,以替换代码中的conj。在您的情况下,如果所有函数都是带有2个childreen的节点,则它不起作用,您不能向两个子节点发送acc。为什么要尾部递归?只有当您想要生成深度大于Java堆栈的树时,才需要这个。Java拥有1000帧深的堆栈没有问题。尾部递归可能比您的版本慢。