【发布时间】:2021-03-08 01:53:31
【问题描述】:
假设我有以下树:
在我的程序中,这棵树用一个列表表示:'(+ (* 5 6) (sqrt 3))。
如何通过索引获取子树?
索引应该从 0 开始并且是深度优先的。在上图中,我用索引标记了所有节点以显示这一点。
例如:
(define tree '(+ (* 5 6) (sqrt 3)))
(subtree tree 0) ; Returns: '(+ (* 5 6) (sqrt 3)))
(subtree tree 1) ; Returns: '(* 5 6)
(subtree tree 2) ; Returns: 5
(subtree tree 3) ; Returns: 6
(subtree tree 4) ; Returns: '(sqrt 3)
(subtree tree 5) ; Returns: 3
我尝试像这样实现subtree:
(define (subtree tree index)
(cond [(= index 0) tree]
[else
(subtree (cdr tree)
(- index 1))]))
但是,这不会遍历子列表。这是不正确的。
编辑:
我尝试使用延续传递样式实现subtree:
(define (subtree& exp index counter f)
(cond [(= counter index) exp]
[(null? exp) (f counter)]
[(list? exp)
(let ((children (cdr exp)))
(subtree& (car children)
index
(+ counter 1)
(lambda (counter2)
(if (null? (cdr children))
(f counter)
(subtree& (cadr children)
index
(+ counter2 1)
f)))))]
[else (f counter)]))
(define (subtree tree index)
(subtree& tree
index
0
(lambda (_)
(error "Index out of bounds" index))))
这适用于以下树:
'(+ 1 2)'(+ (* 5 6) (sqrt 3))
但是,对于像这样的树,它会失败:
'(+ 1 2 3)
我的实现有什么问题?
【问题讨论】: