我在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中的列表时没有遇到太多问题 - 我似乎得到了它们。但是翻译成树木会给我带来一个问题 - 原则上我不会得到这些东西,这意味着我不断在树问题上获得这些与列表相关的错误消息。我试图继续使用抽象类型(树和节点)而不考虑列表。 我是否以正确的方式解决这个问题?任何有助于理解我缺少哪些与树木一起工作的帮助非常感谢。
答案 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,因为这个树有多个子节点,而树结构只有两个。由于结构严格,这棵树的值也可以成对。