【问题标题】:Binary Trees in SchemeScheme中的二叉树
【发布时间】:2010-02-08 17:23:14
【问题描述】:

考虑以下定义数字树的 BNF。 请注意,一棵树可以是叶子、具有一个子树的节点 1 或节点 2 有两个子树。

tree ::= (’leaf number)
| (’node-1 tree)
| (’node-2 tree tree)

一个。为这些树上的递归过程编写一个模板。

b.定义返回 t中的叶子数

> (leaf-count ’(leaf 5))

1

> (leaf-count ’(node-2 (leaf 25) (leaf 17)))

2

> (leaf-count ’(node-1
(node-2 (leaf 4)
(node-2 (leaf 2) (leaf 3)))))

3

这是我目前所拥有的:

;define what a leaf, node-1, and node-2 is
(define leaf list)
(define node-1 list)
(define node-2 list)

;procedure to decide if a list is a leaf or a node
(define (leaf? tree) (number? (car tree)))
(define (node? tree) (pair? (car tree)))

(define (leaf-count tree)
 (cond ((null? tree) 0)
        ((number? tree) 0)
        ((leaf? tree) 1)
        (else (+ (leaf-count (car tree))
                 (leaf-count (cdr tree))))))

看起来它应该运行得很好,但是当我尝试使用一个简单的测试用例来运行它时

(leaf-count '(leaf 5))

我收到以下错误消息:

car:需要类型对的参数;给定叶子

这个错误信息是什么意思?我将叶子定义为列表。但是由于某种原因,它没有看到它并给了我那个错误消息。

【问题讨论】:

  • 当我读到你的问题时,我不知道如何回答,因为我不知道你知道该怎么做。您需要知道如何在方案中制作列表结构吗?你能做一个递归遍历列表的函数吗?太多未知数。
  • 我有一些代码试图解决这个问题(见上文)。你能看看它并帮我解决它吗?

标签: scheme binary-tree racket


【解决方案1】:

确实,解决别人的任务很有趣。

(define leaf-count
  (match-lambda 
   [(list 'leaf x)     1]
   [(list 'node-1 t)   (leaf-count t)]
   [(list 'node-2 l r) (+ (leaf-count l) (leaf-count r))]))

【讨论】:

  • 感谢您的回复,但我无法运行它。我收到错误消息“对未定义标识符的引用:match-lambda”。你能解释一下“match-lambda”的作用吗?
  • 您使用的是哪种语言级别? match-lambda 是“方案”语言的一部分,因此您应该在 DrScheme 定义窗口的顶部有 #lang scheme。您可以在 PLT 方案指南 (docs.plt-scheme.org/guide/match.html) 中阅读有关 match-lambda 的更多信息。
  • 顺便说一下,我使用的语言是根据 Friedman 和 Wand 的《编程语言精要》第 3 版一书的课程所需的教学语言。
【解决方案2】:

您引用了叶 (leaf-count '(leaf 5)),所以它是一个符号,而不是您之前定义的变量。这是错误的原因,但不是您应该解决的问题。您的三个定义没有多大意义,并且您检测叶子或节点的程序与 BNF 规范不匹配。

这是您自己示例中的一棵树:’(node-1 (node-2 (leaf 4) (node-2 (leaf 2) (leaf 3))))。它被引用了,所以node-1node-2leaf 只是符号,不需要定义。现在编写leaf?node? 函数来检测上面树的各种元素是什么。这是一个测试用例,所有函数调用都应该返回 true:

(define a-tree ’(node-1 (node-2 (leaf 4) (node-2 (leaf 2) (leaf 3)))))
(node? a-tree)
(node? (car (cdr a-tree)))
(leaf? (car (cdr (car (cdr a-tree)))))
(node? (car (cdr (cdr (car (cdr a-tree))))))
(leaf? (car (cdr (car (cdr (cdr (car (cdr a-tree))))))))

一旦这工作,计数也应该没有问题(尽管你当前的方法不起作用,我建议编写左子树和右子树函数来帮助你)。

【讨论】:

    【解决方案3】:

    这是我目前所拥有的:

     ;define what a leaf, node-1, and node-2 is
    (define leaf list)
    (define node-1 list)
    (define node-2 list)
    
    ;procedure to decide if a list is a leaf or a node
    (define (leaf? tree) (number? (cadr tree)))
    (define (node? tree) (pair? (cadr tree)))
    
    (define (leaf-count tree)
     (cond ((null? tree) 0)
            ((number? tree) 0)
            ((leaf? tree) 1)
            (else (+ (leaf-count (car tree))
                     (leaf-count (cdr tree))))))
    

    我对其进行了细微的调整:更改条件以检查列表的 cadr,因为它包含信息。在这种情况下,列表的汽车只是数据是什么(叶子、节点等)的标签。不完全的。我让它适用于最基本的测试用例,但不适用于更复杂的测试用例,例如

    (leaf-count '(node-2 (leaf 25) (leaf 17)))
    

    【讨论】:

    • 顺便说一下,我使用的语言是根据 Friedman 和 Wand 的《编程语言精要》第 3 版一书的课程所需的教学语言。
    • 这修复了示例,但不会更普遍地工作。基本问题是您的程序假设树是一种方式,而您的测试程序使它们以不同的方式。尝试运行 (leaf 5) 然后运行 ​​'(leaf 5) 看看有什么不同。
    • 测试由讲师提供。我必须让它接受它作为输入。
    猜你喜欢
    • 2013-10-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-01-09
    • 1970-01-01
    • 2017-04-14
    • 2011-09-16
    相关资源
    最近更新 更多