我很可能在学习Clojure的第一天就开始学习函数了,但是我觉得我很有野心,并且做了一个递归函数,将浮点值转换成三元函数。如果我用名称来调用函数,而不是使用recur,那么它工作得很好。我理解的问题是,我只是在recur1的版本的函数,有一个标准的方法来处理递归的多重性函数吗?我正在读的那本书似乎没有涵盖它。
(defn float-to-ternary
([x k s]
(def a (int x))
(def r (- x a))
(def carry-string (str s (. Integer toString a 3)))
(cond
(== r 0) carry-string
(> k 20) carry-string
:default (recur (* 3 r) (inc k) carry-string)
)
)
([x]
(def a (int x))
(def r (- x a))
(def carry-string (str (. Integer toString a 3) "."))
(cond
(== r 0) (str (. Integer toString a 3))
:default (recur (* 3 r) 1 carry-string)
)
)
)发布于 2018-03-29 02:07:17
如果您想要“将recur转换为不同的特性”,只需显式调用函数,而不是使用recur
(defn float-to-ternary
([x k s]
(def a (int x))
(def r (- x a))
(def carry-string (str s (. Integer toString a 3)))
(cond
(== r 0) carry-string
(> k 20) carry-string
:default (recur (* 3 r) (inc k) carry-string)))
([x]
(def a (int x))
(def r (- x a))
(def carry-string (str (. Integer toString a 3) "."))
(cond
(== r 0) (str (. Integer toString a 3))
:default (float-to-ternary (* 3 r) 1 carry-string))))这里很安全。当您不使用recur时,您“花费”了一个堆栈框架,但是其余的递归使用recur,所以这很好。
不过,我也有一些强制性的建议:
def,除非您确实有一个很好的理由。def创建的全局变量在函数返回时不会超出作用域!cond的使用是不必要的。- In the first body, you want to return `carry-string` for the first two conditions. You could just make that one condition, connecting the two with an `or`, which lets you simply use `if`.
- Since the second use only has two outcomes, `if` again makes more sense.
考虑到这一点,您的代码看起来更像是:
(defn float-to-ternary
([x k s]
(let [a (int x)
r (- x a)
carry-string (str s (. Integer toString a 3))]
(if (or (> k 20) (== r 0))
carry-string
(recur (* 3 r) (inc k) carry-string))))
([x]
(let [a (int x)
r (- x a)
carry-string (str (. Integer toString a 3) ".")]
(if (== r 0)
(str (. Integer toString a 3))
(float-to-ternary (* 3 r) 1 carry-string)))))https://stackoverflow.com/questions/49546574
复制相似问题