在Scheme中跨树节点应用函数

时间:2016-08-19 20:14:07

标签: list tree scheme

我在Dr. Racket中使用Simply Scheme。

问题是编写树图,类似于深图,但对于树,使用基准和子选择器。这是深图:

(define (deep-map f structure)
  (cond ((word? structure) (f structure))
        ((null? structure) '())
        (else (cons (deep–map f (car structure))
                    (deep–map f (cdr structure))))))

到目前为止,这是我对树图的尝试:

(define (tree-map f structure)
  (cond ((leaf? structure)
         (f (datum structure)))
        (else
         (cons (tree-map f (car (children structure)))
               (tree-map f (cdr (children structure)))))))

这些是树的构造函数和选择器:

(define (make-node datum children)
  (cons datum children))

(define (datum node)
  (car node))

(define (children node)
  (cdr node))

(define (leaf datum)
  (make-node datum '()))

(define (leaf? node)
  (null? (children node)))

对于我的测试用例,我使用带有函数的数字树,例如square:

(define number-tree
  (make-node
   '56
   (list (make-node
          '2
          (children '(34  25 7 89)))
         (make-node
          '32
          (list (make-node
                 '27
                 (children '(13 55 80)))
                (make-node
                 '1098
                 (children '(45 785 98)))
                (make-node '123 (children '(9046)))))
         (make-node '23 (children '(1 9)))
         (make-node '867
            (children '(1 3 5 78)))
         (make-node
          '0
          (list 
           (make-node '78 (children '(984)))
           (make-node '45
              (children '(23 46 78467)))
           (make-node '3 (children '(2))))))))

我收到的错误信息包括&#c; cdr,合同违规,预期配对。'到目前为止,我在使用Scheme中的列表时没有遇到太多问题 - 我似乎得到了它们。但是翻译成树木会给我带来一个问题 - 原则上我不会得到这些东西,这意味着我不断在树问题上获得这些与列表相关的错误消息。我试图继续使用抽象类型(树和节点)而不考虑列表。 我是否以正确的方式解决这个问题?任何有助于理解我缺少哪些与树木一起工作的帮助非常感谢。

1 个答案:

答案 0 :(得分:1)

您的children程序是一个访问者,而不是构造函数。因此:

(make-node
          2
          (children '(34  25 7 89))

应该是:

(make-node 2
           (list (leaf 34)
                 (leaf 25)
                 (leaf 7)
                 (leaf 89)))

你可以像书中那样做,并有办法制作叶子,也许是这样的:

(define (leafs lst-values)
  (map leaf lst-values))

(make-node 2 (leafs '(34  25 7 89)))

不是叶子的树节点具有值,如我的节点示例中的2,而一般树结构叶子是除了一对之外的任何值,而一对是具有两个子节点的节点。这是tree-map,适用于由make-node生成的树:

(define (tree-map proc tree)
  (let aux ((tree tree))
    (make-node (proc (datum tree))
               (map aux (children tree)))))

请注意,对于leaf节点(children tree)'()(map anything '())始终变为'(),以便make-node成为新叶子。递归是通过map,因为这个树有多个子节点,而树结构只有两个。由于结构严格,这棵树的值也可以成对。