我正在使用Clojure处理一些Lisp exercises。我试图在不利用向量和一些Clojure函数的情况下完成这些练习。
此功能
(defn rev-seq
[s1]
(concat (pop s1) (list (peek s1))))
将列表的第一个元素放在最后。我想多次调用此函数来反转列表(不调用Clojure的reverse
函数)。
我不确定在它的位置使用什么。我已经尝试过地图,应用和重复但没有成功。我宁愿有办法对此进行不同的思考,而不是直接回答,但我不是要求讨论。
答案 0 :(得分:4)
首先,如果您想处理一般序列,我认为您需要将rev-seq转换为使用first
/ rest
而不是peek
/ pop
- 在Clojure 1.4中的leas peek
/ pop
似乎需要PersistentStack:
(defn rev-seq
[s1]
(concat (rest s1) (list (first s1))))
然后您应该注意,重复应用此函数将“循环”列表而不是反转它。如果您使用iterate
查看少量应用程序的结果,您可以看到:
(def s '(1 2 3 4 5 6 7 8 9))
(nth (iterate rev-seq s) 3)
=> (4 5 6 7 8 9 1 2 3)
可行的选项是使用递归函数反转:
(defn reverse-seq [s]
(concat (reverse (next s)) (list (first s))))
(reverse-seq s)
=> (9 8 7 6 5 4 3 2 1)
或者你可以使用clojure.core中的技术进行反向:
(defn reverse-seq [s]
(reduce conj () s))
(reverse-seq s)
=> (9 8 7 6 5 4 3 2 1)
希望这会给你一些想法!
答案 1 :(得分:1)
递归很强大! 我翻译了 the solution 进入Clojure。
(defn- inverte-aux
[lista resto]
(if lista
(recur (next lista) (cons (first lista) resto))
resto))
(defn inverte
[lista]
(inverte-aux lista nil))
user> (inverte [4 3 2 1 3])
(3 1 2 3 4)