查找Scheme中从根到叶子的所有路径
给定一棵树,我想找到从根到每片叶子的路径。
因此,对于这棵树:
D
/
B
/ \
A E
\
C-F-G
从根(A)到叶子(D,E,G)有以下路径:
(A B D), (A B E), (A C F G)
如果我将上面的树表示为(A(BDE)(C(FG)))
然后函数 g
就完成了任务:
(define (paths tree)
(cond ((empty? tree)
'())
((pair? tree)
(map (lambda (path)
(if (pair? path)
(cons (car tree) path)
(cons (car tree) (list path))))
(map2 paths (cdr tree))))
(else
(list tree))))
(define (map2 fn lst)
(if (empty? lst)
'()
(append (fn (car lst))
(map2 fn (cdr lst)))))
但这看起来完全错误。我已经有一段时间没有进行这种思考了,但我觉得应该有一种更简洁的方法来做到这一点。任何更好的解决方案(任何语言)的想法将不胜感激。
编辑 - 将 Svante 的解决方案映射到方案中给出:
(define (paths tree)
(if (pair? tree)
(append-map (lambda (node)
(map (lambda (path)
(cons (car tree) path))
(paths node)))
(cdr tree))
(list (list tree))))
这比我原来的要整洁得多。
Given a tree, I want to find the paths from the root to each leaf.
So, for this tree:
D
/
B
/ \
A E
\
C-F-G
has the following paths from root (A) to leaves (D, E, G):
(A B D), (A B E), (A C F G)
If I represent the tree above as (A (B D E) (C (F G)))
then the function g
does the trick:
(define (paths tree)
(cond ((empty? tree)
'())
((pair? tree)
(map (lambda (path)
(if (pair? path)
(cons (car tree) path)
(cons (car tree) (list path))))
(map2 paths (cdr tree))))
(else
(list tree))))
(define (map2 fn lst)
(if (empty? lst)
'()
(append (fn (car lst))
(map2 fn (cdr lst)))))
But this looks all wrong. I've not had to do this kind of thinking for a while, but I feel there should be a neater way of doing it. Any ideas for a better solution (in any language) would be appreciated.
EDIT - Mapping Svante's solution into Scheme gives:
(define (paths tree)
(if (pair? tree)
(append-map (lambda (node)
(map (lambda (path)
(cons (car tree) path))
(paths node)))
(cdr tree))
(list (list tree))))
which is much neater than my original.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
我更熟悉 Common Lisp。
I am more fluent in Common Lisp.
Svante 答案的 R5RS 翻译:
R5RS translation of Svante's answer:
我认为您可以将示例树定义为(根左右)每个树都是一个列表。所以你的示例树将是: (D (B (A () (C () (F () G ) ) ) E) () ) 并且更容易遍历
I think you could define the example tree as (root left right) each one a list. So your example tree would be: (D (B (A () (C () (F () G ) ) ) E) () ) and that is easier to traverse
您需要一个树搜索算法。广度优先或深度优先遍历都可以,在这种情况下没有区别,因为您需要爬行整个树。每当您到达叶子时,只需将当前路径存储在结果中即可。
You want a tree-search algorithm. Breadth-first or depth-first traversal would both work, and it makes no difference which, in this case, since you need to crawl the entire tree. Whenever you get to a leaf, just store the current path in your results.