Clojure - 使用递归来查找列表中的元素数

时间:2017-01-03 16:08:36

标签: list recursion clojure

我编写了一个函数,它使用递归来查找列表中的元素数量并且它成功运行但是,我并不特别喜欢我编写它的方式。现在我已经用一种方式编写了它,我似乎无法想到采用不同的方式。

我的代码如下:

(def length 
 (fn [n]
  (loop [i n total 0]
   (cond (= 0 i) total
     :t (recur (rest i)(inc total)))))) 

对我来说,似乎它过于复杂,任何人都可以想到另一种可以写作比较的方法吗?

非常感谢任何帮助。

4 个答案:

答案 0 :(得分:2)

以下代码显示了一些不同的解决方案。通常,您应该使用内置函数count

(def data [:one :two :three])

(defn count-loop [data]
  (loop [cnt 0
         remaining data]
    (if (empty? remaining)
      cnt
      (recur (inc cnt) (rest remaining)))))

(defn count-recursive [remaining]
    (if (empty? remaining)
      0
      (inc (count-recursive (rest remaining)))))

(defn count-imperative [data]
  (let [cnt (atom 0)]
    (doseq [elem data]
      (swap! cnt inc))
    @cnt))

(deftest t-count
  (is (= 3 (count data)))
  (is (= 3 (count-loop data)))
  (is (= 3 (count-recursive data)))
  (is (= 3 (count-imperative data))))

答案 1 :(得分:2)

这是一个天真的递归版本:

(defn my-count [coll]
    (if (empty? coll) 
        0 
        (inc (my-count (rest coll)))))

请记住,这里不会有任何尾调用优化,所以对于长列表,堆栈会溢出。

以下是使用reduce的版本:

(defn my-count [coll]
    (reduce (fn [acc x] (inc acc)) 0 coll))

答案 2 :(得分:1)

这是一个尾调优化的,并且不依赖于controller。基本上与Alan Thompson的第一个相同,但内在功能是最好的。 (并且对我来说感觉更加惯用。):-)

loop

答案 3 :(得分:0)

为了完整起见,这是另一个转折

(defn my-count
  ([data]
   (my-count data 0))
  ([data counter]
   (if (empty? data)
     counter
     (recur (rest data) (inc counter)))))