use*_*565 1 recursion sum clojure
我将用Python描述我想做什么(我想在Clojure中写这个).我有这个功能:
def f(n):
s=0
for d in range(1,n+1):
s+=d*(n//d)
return(s)
Run Code Online (Sandbox Code Playgroud)
这基本上是从d = 1到n包含循环,并且总结了d/d的最低值的d倍的值.
在Clojure中我想让它成为一个递归函数.Python等价物:
def f(d, n):
if d == 0: return 0
else: return d*(n//d) + f(d-1, n)
Run Code Online (Sandbox Code Playgroud)
然后我会调用函数f(n, n).
我在尝试这个:
(defn f
([n] (f n n))
([d n]
(if (> d 0)
(recur (dec d) n)
0)))
Run Code Online (Sandbox Code Playgroud)
但是我不知道到目前为止这是否正确,或者在总和或者如何做到这一点等等.
如果你看看你的Clojure f函数,那么[d n]arity会再次出现
d 递减和n 不变...... d当它返回时为零0.
如果我们将这个arity写成一个独特的本地函数,使用letfn,我们可以删除不变的n参数,从f参数中提取它:
(defn f [n]
(letfn [(g [d]
(if (> d 0)
(recur (dec d))
0))]
(g n)))
Run Code Online (Sandbox Code Playgroud)
这当然会产生错误的答案,总是返回0:
(f 10)
=> 0
Run Code Online (Sandbox Code Playgroud)
但我们可以看到将总和放在哪里:
(defn f [n]
(letfn [(g [d]
(if (> d 0)
(+ (* d (quot n d)) (g (dec d)))
0))]
(g n)))
Run Code Online (Sandbox Code Playgroud)
我们必须将其恢复recur为显式的递归调用g,因为它被包围了+.
但至少它有效:
(f 10)
=> 87
Run Code Online (Sandbox Code Playgroud)
在Clojure中我想让它成为一个递归函数.
别.我上面已经做过,只是为了告诉你计算的位置.
在惯用语Clojure中,显式递归很少见.更好地使用封装其常见模式的函数.我不会重复Carciginate给出的内容,但是一旦你习惯了线程宏,我认为你会发现以下简洁明了:
(defn f [n]
(->> (range 1 (inc n))
(map (fn [d] (* d (quot n d))))
(reduce +)))
Run Code Online (Sandbox Code Playgroud)
顺便说一下,Python代码的合理模拟是
(defn f [n]
(loop [s 0, d 1]
(if (> d n)
s
(recur (+ s (* d (quot n d))) (inc d)))))
Run Code Online (Sandbox Code Playgroud)