[英]Recursively reverse a sequence in Clojure
我想在不使用reverse
函數的情況下reverse
Clojure中的序列,並以遞歸方式執行此操作。
這是我想出的:
(defn reverse-recursively [coll]
(loop [r (rest coll)
acc (conj () (first coll))]
(if (= (count r) 0)
acc
(recur (rest r) (conj acc (first r))))))
樣本輸出:
user> (reverse-recursively '(1 2 3 4 5 6))
(6 5 4 3 2 1)
user> (reverse-recursively [1 2 3 4 5 6])
(6 5 4 3 2 1)
user> (reverse-recursively {:a 1 :b 2 :c 3})
([:c 3] [:b 2] [:a 1])
問題:
參考文獻:
http://groups.google.com/group/clojure/browse_thread/thread/4e7a4bfb0d71a508?pli=1
acc
,因為原始輸入可能是空的(而且代碼更多)。 (defn reverse-recursively [coll] (loop [[r & more :as all] (seq coll) acc '()] (if all (recur more (cons r acc)) acc)))
至於loop
/ recur
和acc
,你需要一些傳遞工作逆轉列表的方法。 它是loop
,或者為函數添加另一個參數(這實際上是loop
正在做什么)。
或者使用更高階函數:
user=> (reduce conj '() [1 2 3 4]) (4 3 2 1)
對於exhaustivenes起見,有使用一個更方法into
。 由於內部使用conj
它可以使用如下:
(defn reverse-list
"Reverse the element of alist."
[lst]
(into '() lst))
對問題1是肯定的,這就是我對遞歸公式的回答(我無法告訴你它是否是好的clojure練習)。
(defn recursive-reverse [coll]
(if (empty? coll)
[]
(conj (recursive-reverse (rest coll)) (first coll) )))
在當前版本的Clojure中,有一個名為rseq
的內置函數。 對於經過的人。
(defn reverse-seq [sss]
(if (not (empty? sss))
(conj (reverse-seq (rest sss)) (first sss))
)
)
(defn recursive-reverse [coll]
(if (empty? coll)
()
(concat (vector (peek coll)) (recursive-reverse (pop coll )))
)
)
and test:
user=> (recursive-reverse [1])
(1)
user=> (recursive-reverse [1 2 3 4 5])
(5 4 3 2 1)
(defn my-rev [col]
(loop [ col col
result []]
(if (empty? col)
result
(recur (rest col) (cons (first col) result)))))
Q1。
JVM無法優化遞歸,這是一種直接和堆棧溢出的遞歸函數。 因此,在使用loop / recur的Clojure中。 因此,不使用無法定義重復深度遞歸的函數。 (它也在內部用作功能蹦床。)
Q2。
reur的遞歸函數必須是尾遞歸的。 如果正常的遞歸函數改變為尾遞歸函數,那么需要攜帶一個變量值作為累加器。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.