【发布时间】:2016-07-26 20:33:14
【问题描述】:
考虑一棵树,它由以下递归定义定义:
一棵树应该是一个包含两个元素的向量:第一个是一个数字,第二个是一个树列表或 nil。
以下 clojure 数据结构就是一个示例:
(def tree '[9 ([4 nil]
[6 nil]
[2 ([55 nil]
[22 nil]
[3 ([5 nil])])]
[67 ([44 nil])])])
这个结构应该被转换成所有可能的向下连接的列表,可以从任何节点到它的子节点。连接应表示为包含父节点值和子节点值的向量。顺序不重要:
(def result '([9 4]
[9 6]
[9 2]
[2 55]
[2 22]
[2 3]
[3 5]
[9 67]
[67 44])
我想出了这个解决方案:
(defn get-connections [[x xs]]
(concat (map #(vector x (first %)) xs)
(mapcat get-connections xs)))
而且,确实:
(= (sort result)
(sort (get-connections tree)))
;; true
但是,有没有更好的方法来使用普通的 clojure? 在这种方法中,我遍历每个节点的子节点两次,应该避免这种情况。在这种特殊情况下,不需要尾递归,所以一个简单的递归版本就可以了。
此外,我很感兴趣可以使用哪些更高级别的抽象来解决这个问题。那么 Zippers 或 Clojure/Walk 呢?最后:哪些技术也可以在 ClojureScript 中使用?
【问题讨论】:
标签: clojure tree clojurescript