使用 clojure.zip 进行后序树遍历以编辑节点
我有一棵表示为嵌套向量的树。我想要对树进行 indexed
的概括,显示每个节点的索引,如下所示,
(visit 42); => [0 42]
(visit [6 7]); => [0
; [[0 6]
; [1 7]]]
天真的实现将直接使用 clojure.zip (正如这里已经问过的)
(defn visit [tree]
(loop [loc (vector-zip tree)]
(if (end? loc)
(root loc)
(recur
(next (edit loc #(conj
[(count (lefts loc))]
%)))))))
但是使用 clojure.zip/next
重复执行前序遍历,导致无限循环这种情况(未访问的节点被无限地conj
编辑到[:found]
向量中)。另一种方法是使用 clojure.walk/postwalk,但它不提供结构信息,例如索引。
你会如何实施这个?是否有一个 zip 的 postorder-next 可以立即解决这个问题?
I have a tree represented as a nested vector. I want to have a generalization of indexed
for trees, showing the index of each node like this,
(visit 42); => [0 42]
(visit [6 7]); => [0
; [[0 6]
; [1 7]]]
The naive implementation would use clojure.zip directly (as already asked here)
(defn visit [tree]
(loop [loc (vector-zip tree)]
(if (end? loc)
(root loc)
(recur
(next (edit loc #(conj
[(count (lefts loc))]
%)))))))
But recurring with clojure.zip/next
performs a preorder traversal, resulting in an infinite loop in this case (unvisited nodes get conj
ed into a [:found]
vector infinitely). Another approach would be using clojure.walk/postwalk
, but it doesn't provide structural information, such as index.
How would you implement this? Is there a postorder-next
for zip that would solve it right away?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
我不确定我是否理解您要做什么,但这些示例向我表明分配给节点的索引对应于它们左兄弟的数量(因为在第二个示例中根节点和 < code>6 子级标记为
0
)。 更新:显然我第一次只是误读了visit
示例 - 它使意图足够清晰......幸运的是,现在我正确地阅读了它,在我看来,下面的答案是正确。如果这是正确的,这是一个基于
clojure.walk/postwalk
的解决方案:使用给定的示例:
更新:使用
的简单解决方案>map-indexed
(1.2 中提供;在 1.1 中使用map
+clojure.contrib.seq-utils/indexed
):I'm not sure if I understand what you're trying to do, but the examples suggest to me that the indices assigned to the nodes correspond to the number of their left siblings (since in the second example both the root node and the
6
child are labelled with0
). Update: Apparently I simply misread thevisit
example the first time round -- it makes the intention clear enough... Fortunately now that I read it properly it seems to me that the answer below is correct.If that is correct, this is a
clojure.walk/postwalk
-based solution:With the given examples:
Update: A simple solution using
map-indexed
(available in 1.2; usemap
+clojure.contrib.seq-utils/indexed
in 1.1):