查找Scheme中从根到叶子的所有路径

发布于 2024-09-05 08:45:32 字数 1139 浏览 3 评论 0原文

给定一棵树,我想找到从根到每片叶子的路径。

因此,对于这棵树:

    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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

我一直都在从未离去 2024-09-12 08:45:32

我更熟悉 Common Lisp。

(defun paths (tree)
  (if (atom tree)
      (list (list tree))
      (mapcan (lambda (node)
                (mapcar (lambda (path)
                          (cons (car tree) path))
                        (paths node)))
              (cdr tree))))

CL-USER> (paths '(A (B D E) (C (F G))))
((A B D) (A B E) (A C F G))

I am more fluent in Common Lisp.

(defun paths (tree)
  (if (atom tree)
      (list (list tree))
      (mapcan (lambda (node)
                (mapcar (lambda (path)
                          (cons (car tree) path))
                        (paths node)))
              (cdr tree))))

CL-USER> (paths '(A (B D E) (C (F G))))
((A B D) (A B E) (A C F G))
牵你手 2024-09-12 08:45:32

Svante 答案的 R5RS 翻译:

(define (accumulate op init seq)
  (define (iter ans rest)
    (if (null? rest)
        ans
        (iter (op ans (car rest))
              (cdr rest))))
  (iter init seq))

(define (flatten seq)
  (accumulate append '() seq))

(define (flatmap op seq)
  (flatten (map op seq)))

(define (atom? x)
  (not (pair? x)))

(define (paths tree)
  (if (atom? tree)
      (list (list tree))
      (flatmap (lambda (node)
                 (map (lambda (path)
                        (cons (car tree) path))
                      (paths node)))
               (cdr tree))))

R5RS translation of Svante's answer:

(define (accumulate op init seq)
  (define (iter ans rest)
    (if (null? rest)
        ans
        (iter (op ans (car rest))
              (cdr rest))))
  (iter init seq))

(define (flatten seq)
  (accumulate append '() seq))

(define (flatmap op seq)
  (flatten (map op seq)))

(define (atom? x)
  (not (pair? x)))

(define (paths tree)
  (if (atom? tree)
      (list (list tree))
      (flatmap (lambda (node)
                 (map (lambda (path)
                        (cons (car tree) path))
                      (paths node)))
               (cdr tree))))
勿挽旧人 2024-09-12 08:45:32

我认为您可以将示例树定义为(根左右)每个树都是一个列表。所以你的示例树将是: (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

森林迷了鹿 2024-09-12 08:45:32

您需要一个树搜索算法。广度优先或深度优先遍历都可以,在这种情况下没有区别,因为您需要爬行整个树。每当您到达叶子时,只需将当前路径存储在结果中即可。

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文