使用连续传递样式通过广度优先索引获取子树

问题描述

这个问题是对 How do I get a subtree by index? 的跟进。该问题涉及深度优先索引(为此我提供了深度优先连续传递样式解决方案)。这里的问题是关于广度优先索引,特别是关于使用连续传递样式 (cps) 解决问题。

假设我有一棵树代表 '(+ (* 5 6) (sqrt 3))


GraphViz:
digraph mytree {
forcelabels=true;
node [shape=circle];
"+"->"";
"+"->"sqrt";
node [shape=rect];
""->5;
""->6;
"sqrt"->3;
"+" [xlabel="0"];
"" [xlabel="1"];
"sqrt" [xlabel="2"];
"5" [xlabel="3"];
"6" [xlabel="4"];
"3" [xlabel="5"];
}
dot -Tpng tree.dot -O

节点的索引从根的 0 开始,并且是广度优先的。在上图中,我用索引标记了所有节点以显示这一点。

我想定义一个函数 subtree-bfs,它接受​​一棵树和一个索引号,并返回以给定索引为根的子树。例如:

(define tree '(+ (* 5 6) (sqrt 3)))

(subtree-bfs tree 0)  ; Returns: '(+ (* 5 6) (sqrt 3)))
(subtree-bfs tree 1)  ; Returns: '(* 5 6)
(subtree-bfs tree 2)  ; Returns: '(sqrt 3)
(subtree-bfs tree 3)  ; Returns: 5
(subtree-bfs tree 4)  ; Returns: 6
(subtree-bfs tree 5)  ; Returns: 3

我想使用延续传递风格来解决这个问题。我如何定义 subtree-bfs


到目前为止,我有这个:

(define (node-children node)
  ;; (node-children 123) -> '()
  ;; (node-children (+ 1 (+ 2 3))) -> '(1 (+ 2 3))
  (cond [(pair? node) (cdr node)]
        [(null? node) (error "Invalid node" node)]
        [else '()]))

(define (traverse-row& nodes index counter k)
  ;; 'counter' is the index number of the first node in 'nodes'.
  (cond [(null? nodes) (k counter)]
        [(= counter index) (car nodes)]
        [else
         (traverse-row& (cdr nodes)
                        index
                        (+ counter 1)
                        k)]))

(define (children-k children index k)
  (if (null? children)
      k
      (lambda (counter)
        (subtree-bfs& (car children)
                      index
                      counter
                      (children-k (cdr children) index k)))))

(define (subtree-bfs& nodes index counter k)
  (traverse-row& nodes
                 index
                 counter
                 (children-k (map node-children nodes)
                             index
                             k)))

(define (subtree-bfs tree index)
  (subtree-bfs& (list tree)
                index
                0
                (lambda (max-index+1)
                  ;; (- max-index+1 1) represents the maximum valid index number.
                  (error "Index out of bounds" index))))

此实现似乎可以正常工作。不过,好像还挺长的。由于我对cps没有经验,所以我认为必须有更好的cps解决方案来解决这个问题。有没有更好的 cps 解决方案?

注 1:请原谅我没有充分注释代码。我必须承认我自己并不完全理解解决方案(!)我很惊讶我能够首先找到解决方案。

注2:这个问题可能更适合代码审查网站。但是,考虑到那里对 Scheme 和 Racket 缺乏关注,这样的问题可能永远不会得到回答。

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)