【问题标题】:Apply function across tree nodes in Scheme在 Scheme 中跨树节点应用函数
【发布时间】:2016-08-19 20:14:07
【问题描述】:

我在 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))))))))

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

【问题讨论】:

    标签: list tree scheme


    【解决方案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,而一般的树结构叶子是除了一对之外的任何东西,一对是具有两个子节点的节点。这是一个在make-node 制作的树上工作的tree-map

    (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 会生成一个新叶子。递归是通过映射,因为这棵树有多个孩子,而树结构只有两个。由于结构严格,这棵树的值也可以是对的。

    【讨论】:

    • 谢谢,这很有帮助。树形图确实有效。很高兴理解我在数字树上犯的错误。
    猜你喜欢
    • 2013-10-26
    • 2012-09-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-07-23
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多