问题描述
我是Racket的初学者,并且遇到了以下问题:
- 定义一个结构
node
,该结构具有以下字段:value
,left
,middle
,right
。该结构表示树结构中的节点。
这些字段包含存储在节点,左侧子树中的值, 中间的子树和右边的子树。如果是子树 不存在,则对应的字段应包含emptyNode
,如下所述。- 定义结构
emptyNode
,以在树中指定一个空节点。- 编写一个函数
treeFold
,该函数以一个函数f
,一个初始值initial
和一个树结构tree
作为参数。这应该 然后产生一个单一值,该值是使用f
折叠 树中的值(在其中使用left
,middle
和right
子树 订购)。请注意,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