球拍中的树褶

问题描述

我是Racket的初学者,并且遇到了以下问题:

  • 定义一个结构node,该结构具有以下字段:valueleftmiddleright。该结构表示树结构中的节点。
    这些字段包含存储在节点,左侧子树中的值, 中间的子树和右边的子树。如果是子树 不存在,则对应的字段应包含 emptyNode,如下所述。
  • 定义结构emptyNode,以在树中指定一个空节点。
  • 编写一个函数treeFold,该函数一个函数f一个初始值initial一个树结构tree作为参数。这应该 然后产生一个单一值,该值是使用f折叠 树中的值(在其中使用leftmiddleright子树 订购)。请注意,f一个接受两个参数的函数。首先 参数是树中的值,第二个是部分 累积结果。

函数调用应为:

(treeFold (lambda (a acc) (+ a acc)) 15 tree) 

树:

(node 7 (node 5 (emptyNode) (emptyNode) (emptyNode)) 
        (node 20 (emptyNode) (emptyNode) (emptyNode)) 
        (emptyNode))

输出47

这是我到目前为止所做的:

(struct node (value left middle right) #:transparent)

(struct emptyNode () #:transparent)

(define tree 
    (node 7 
          (node 5 (emptyNode) (emptyNode) (emptyNode)) 
          (node 20 (emptyNode) (emptyNode) (emptyNode)) 
          (emptyNode)))

(define (treeFold f initial tree)
  (if (emptyNode? tree)
     (emptyNode)
     (node (f initial (node-value tree))
           (node-left tree)
           (node-middle tree)
           (node-right tree))))

如何获得整片叶子的总数?

任何想法或帮助,谢谢


edit:因此,基于评论中的答案和讨论,我得到了一个功能,但是仍然有一个错误,我找不到它。在这里

(define (treeFold f initial tree) 
  (cond 
    [(emptyNode? tree) 
          (f initial 0)] 
    [else (f (node-value tree) 
             (f (treeFold f 
                   (treeFold f 
                      (treeFold f initial 
                         (node-left tree)) 
                      (node-middle tree)) 
                    (node-right tree))))]))

能否请您告诉我如何解决?谢谢。


编辑:最终代码

(define (treeFold f initial tree) 
  (cond 
    [(emptyNode? tree) (f initial 0)] 
    [else (f  (node-value tree)                
              (treeFold f                   
                   (treeFold f 
                        (treeFold f initial 
                             (node-left tree)) 
                             (node-middle tree)) 
                             (node-right tree)))]))

它按我预期的那样工作

解决方法

使用新版本的功能编辑问题后进行更新。

这是朝正确方向迈出的一步。其中有一些正确的部分,还有一些不正确的部分。

功能就像可以连接在一起的盒子。东西插在一些电线上,东西插在其他电线上。每个盒子都有正确的使用方式:电线的数量,以及预期会流入其中的东西。

您的新版本:

(define (treeFold f initial tree) 
  (cond 
    [(emptyNode? tree) 
          (f initial 0)] 
    [else (f (node-value tree)                 ;; (1)
             (f (treeFold f                    ;; (2)
                   (treeFold f 
                      (treeFold f initial 
                         (node-left tree)) 
                      (node-middle tree)) 
                    (node-right tree))))]))

f需要两个参数。 (f initial 0)至少在这方面看起来正确(1)中的呼叫也是如此。但是,在f处对(2)的调用只有一个参数提供给f,所以不正确。

接下来,就是它的含义。对treeFold的三个嵌套调用几乎在 右边:我们“进入” (node-left tree),即左边的子树,以initial作为初始值,然后从中获取结果,并使用 it 作为新的初始值进入中间子树,并使用计算出的结果遍历正确的子树。真好我们 完成 。那就是我们需要的 final 结果-无需再将其输入f中。因此根本不需要对f的三个嵌套调用之上的对treeFold的两个调用。

除了,(node-value tree)与我们有什么关系?它适合哪里?答案是,应通过调用initial将其与f值组合,并且结果应该将用作遍历 left 子树的初始值;我们开始折叠的值。

基本情况也不正确。我们已经有了initial,为什么突然需要将它与0结合起来?又为什么0?例如,我们可以将一棵拿着 strings 的树折叠起来,并且将字符串与数字0组合起来并没有多大意义。

否,0提供的作为对treeFold的调用中的初始值,例如

(define (sumAllNumbersInWholeTree tree)
  (treeFold + 0 tree))

使用带有字符串的树,我们可以定义

(define (collectAllStringsInWholeTree tree)
  (treeFold string-append "" tree))

答案的初始版本如下。用您的新知识复习其示例(非常编辑)。 :)


对于

(define tree 
    (node 7 
          (node 5 (emptyNode) (emptyNode) (emptyNode)) 
          (node 20 (emptyNode) (emptyNode) (emptyNode)) 
          (emptyNode)))

根据规格必须是

47 == (treeFold + 15 tree)
   == (treeFold + 15 
        (node 7 
          (node 5 (emptyNode) (emptyNode) (emptyNode)) 
          (node 20 (emptyNode) (emptyNode) (emptyNode)) 
          (emptyNode)))
   == (treeFold + 
          (treeFold + 
              (treeFold + (+ 15 7)
                  (node 5 (emptyNode) (emptyNode) (emptyNode)))
              (node 20 (emptyNode) (emptyNode) (emptyNode)))
          (emptyNode))
   == (treeFold + 
          (treeFold + 
              (treeFold +  
                   (treeFold + 
                       (treeFold + (+ 22 5) (emptyNode))
                       (emptyNode))
                   (emptyNode))
              (node 20 (emptyNode) (emptyNode) (emptyNode)))
          (emptyNode))
   == (treeFold + 
          (treeFold + 
              (treeFold +  
                   (treeFold + 27
                       (emptyNode))
                   (emptyNode))
              (node 20 (emptyNode) (emptyNode) (emptyNode)))
          (emptyNode))
   == (treeFold + 
          (treeFold + 
              (treeFold + 27
                   (emptyNode))
              (node 20 (emptyNode) (emptyNode) (emptyNode)))
          (emptyNode))
   == (treeFold + 
          (treeFold + 27
              (node 20 (emptyNode) (emptyNode) (emptyNode)))
          (emptyNode))
   .........

(用==表示“等于”)。这已经为您提供了完整定义所需的一切,即

(treeFold + i (node v lt md rt))
==
(treeFold +
   (treeFold +
      (treeFold + (+ i v) lt)
      md)
   rt)

(treeFold + i (emptyNode))
==
i