[英]Clojure - Using recursion to find the number of elements in a list
我編寫了一個函數,該函數使用遞歸來查找列表中的元素數量,並且可以成功運行,但是,我並不特別喜歡編寫它的方式。 現在,我已經以一種似乎無法想到的另一種方式來編寫它。
我的代碼如下:
(def length
(fn [n]
(loop [i n total 0]
(cond (= 0 i) total
:t (recur (rest i)(inc total))))))
在我看來,這似乎太復雜了,任何人都可以想到另一種可以比較的方式嗎?
任何幫助,不勝感激。
這是顯示一些不同解決方案的代碼。 通常,您應該使用內置函數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))))
這是一個朴素的遞歸版本:
(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))
這是經過尾調用優化的,並且不依賴loop
。 基本上與艾倫·湯普森(Alan Thompson)的第一個相同,但是內部功能才是最好的。 (並且對我來說更習慣):-)
(defn my-count [sq]
(letfn [(inner-count [c s]
(if (empty? s)
c
(recur (inc c) (rest s))))]
(inner-count 0 sq)))
只是為了完整性,這是另一種變化
(defn my-count
([data]
(my-count data 0))
([data counter]
(if (empty? data)
counter
(recur (rest data) (inc counter)))))
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.