Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/symfony/6.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Tree 如何在球拍中折叠树状结构?_Tree_Sum_Racket_Fold - Fatal编程技术网

Tree 如何在球拍中折叠树状结构?

Tree 如何在球拍中折叠树状结构?,tree,sum,racket,fold,Tree,Sum,Racket,Fold,我有一个可以创建树结构的结构: 结构节点值左中右 以及另一个定义叶节点的结构: 结构空节点 我如何制作一个函数,将树折叠成一个值,方法是将这些值相加,从左子树开始,然后从中到右 我正在考虑将树转换为一个列表,首先是左子树,然后是中间子树,然后是右子树,然后在列表上执行foldl,但我不确定如何完成它,或者这是否是正确的方法: (define (treeToList tree) (cond [(node? tree) (append (node-left tree)) (treeToL

我有一个可以创建树结构的结构:

结构节点值左中右

以及另一个定义叶节点的结构:

结构空节点

我如何制作一个函数,将树折叠成一个值,方法是将这些值相加,从左子树开始,然后从中到右

我正在考虑将树转换为一个列表,首先是左子树,然后是中间子树,然后是右子树,然后在列表上执行foldl,但我不确定如何完成它,或者这是否是正确的方法:

(define (treeToList tree)
  (cond
    [(node? tree) (append (node-left tree)) (treeToList (node-left tree))
                  (append (node-middle tree)) (treeToList (node-middle tree))
                  (append (node-right tree)) (treeToList (node-right tree))]
    [else ] ;do nothing, leaf node
    ))

所以,一个很好的方法是使用球拍的模式匹配。除此之外,使用基于议程的搜索也很好,这样整个过程都是迭代的。因此,进行求和的函数将有三个参数:

当前节点; 需要查看的节点的当前议程; 运行总数; 然后它根据匹配这些参数的模式来决定要做什么,在节点上循环并从议程中推送和弹出内容

因此,给出了节点和空节点的定义,以及由它们组成的示例树,如下所示:

(struct node (value left middle right))
(struct empty-node ())

(define sample-tree
  (node 1
        (node 2
              (empty-node)
              (node 3 (empty-node) (empty-node) (empty-node))
              (node -1
                    (node 1 (empty-node) (empty-node) (empty-node))
                    (empty-node)
                    (empty-node)))
        (node 10 (empty-node) (empty-node) (empty-node))
        (empty-node)))
我们可以编写一个函数对树求和,如下所示:

(define (sum-node-tree node-tree)
  (define/match (snt-loop thing agenda sum)
    [((empty-node) '() s)
     ;; an empty node, nothing on the agenda: we're done
     s]
    [((empty-node) (cons next more) s)
     ;; an empty node, but there is an agenda, so start on the next agenda
     ;; item
     (snt-loop next more s)]
    [((node (? number? v) l m r) a s)
     ;; a node with a value: sum the value into the total, push the middle
     ;; and right children onto the agenda, and start on the left child.
     (snt-loop l (list* m r a) (+ s v))]
    [(_ _ _)
     ;; something bad in the tree
     (error 'sum-node-tree "bogus tree")])
  (snt-loop node-tree '() 0))
然后


所以,一个很好的方法是使用球拍的模式匹配。除此之外,使用基于议程的搜索也很好,这样整个过程都是迭代的。因此,进行求和的函数将有三个参数:

当前节点; 需要查看的节点的当前议程; 运行总数; 然后它根据匹配这些参数的模式来决定要做什么,在节点上循环并从议程中推送和弹出内容

因此,给出了节点和空节点的定义,以及由它们组成的示例树,如下所示:

(struct node (value left middle right))
(struct empty-node ())

(define sample-tree
  (node 1
        (node 2
              (empty-node)
              (node 3 (empty-node) (empty-node) (empty-node))
              (node -1
                    (node 1 (empty-node) (empty-node) (empty-node))
                    (empty-node)
                    (empty-node)))
        (node 10 (empty-node) (empty-node) (empty-node))
        (empty-node)))
我们可以编写一个函数对树求和,如下所示:

(define (sum-node-tree node-tree)
  (define/match (snt-loop thing agenda sum)
    [((empty-node) '() s)
     ;; an empty node, nothing on the agenda: we're done
     s]
    [((empty-node) (cons next more) s)
     ;; an empty node, but there is an agenda, so start on the next agenda
     ;; item
     (snt-loop next more s)]
    [((node (? number? v) l m r) a s)
     ;; a node with a value: sum the value into the total, push the middle
     ;; and right children onto the agenda, and start on the left child.
     (snt-loop l (list* m r a) (+ s v))]
    [(_ _ _)
     ;; something bad in the tree
     (error 'sum-node-tree "bogus tree")])
  (snt-loop node-tree '() 0))
然后

您可以为此使用包,特别是接口

使用命名示例树中的树示例,我们首先定义一个函数来获取节点的子节点:

(define (node-children t)
  (list (node-left t)
        (node-middle t)
        (node-right t)))
然后使用它创建树表示:

(require data/lazytree)
(define t (make-tree node-children
                     sample-tree
                     #:with-data node-value
                     #:empty-pred empty-node?))
并使用树状折叠得到结果:

(tree-fold + t)
=> 16
您可以为此使用包,特别是接口

使用命名示例树中的树示例,我们首先定义一个函数来获取节点的子节点:

(define (node-children t)
  (list (node-left t)
        (node-middle t)
        (node-right t)))
然后使用它创建树表示:

(require data/lazytree)
(define t (make-tree node-children
                     sample-tree
                     #:with-data node-value
                     #:empty-pred empty-node?))
并使用树状折叠得到结果:

(tree-fold + t)
=> 16

在第一个第二个答案中有6个表达式。它们是否要组合成一个答案?如果不合并它们,它将丢弃前5个,只返回最后一个。另一件奇怪的事是,您说要求和这些值,但代码在第二个答案中根本不使用节点值字段选择器。在第一个第二个答案中有6个表达式。它们是否要组合成一个答案?如果不合并它们,它将丢弃前5个,只返回最后一个。另一个奇怪的事情是,您说要对值求和,但代码在第二个答案中根本不使用节点值字段选择器