树深:汽车/司机合同违规

时间:2018-02-12 17:51:17

标签: tree lisp racket depth contract

我正在使用球拍来返回给定树的深度。这是当前的代码:

(define (depth tree)
   (cond
      [(empty? tree) 0]
      [else
       (+ 1 (max (depth (cadr tree))
                 (depth (caddr tree))))]))

我无法测试它,因为我总是遇到违反汽车和cdr合同的运行时错误。具体来说,当我尝试

(depth '(1 2 3))

应该返回1,我遇到:

length: contract violation
  expected: list?
  given: 2

无论我做什么,问题仍然存在,我不允许更改测试用例来解决问题。我确信这很简单,但有人可以帮我理解吗?

(我查看了其他帖子;有些人讨论了深度算法,但我要具体询问此处提供的汽车/ cdr合同违规情况。)

3 个答案:

答案 0 :(得分:0)

您的问题的答案包含在您的基本案例中:empty?。什么是'()?它是list的结尾。因此,如果您想知道深度,您需要确保重复出现在相关列表中的任何列表

以下是我在阅读代码时所要求的内容:如果tree有一些元素,则将该元素的深度与下一个元素的深度进行比较。您可能想要问的是,使用列表其余部分的深度来获取该元素的最大深度(这不是caddr它是cdr) 。所以我假设你想要将2的深度设为零(它不是一个列表)。如果是这样,您是否在cond测试中正确列出了这种情况?嗯。也许有办法检查某些东西是否是一对,在这种情况下我们会重复,否则它的深度为0 ......

答案 1 :(得分:0)

这里可能存在一些问题。

首先也是最重要的:您粘贴的错误与“长度”有关,但程序中没有任何“长度”用法。当我运行你的代码时,这是我得到的错误:

cadr: contract violation
  expected: (cons/c any/c pair?)
  given: 2

了解这里发生了什么的最好方法可能是使用步进器。更具体一点:将语言级别设置为“使用列表缩写开始学生”,将以下程序放在定义窗口中,然后单击“步骤”:

(define (depth tree)
   (cond
      [(empty? tree) 0]
      [else
       (+ 1 (max (depth (cadr tree))
                 (depth (caddr tree))))]))

(depth '(1 2 3))

答案 2 :(得分:0)

简答:

使用pair?代替empty?并切换条款。给你:

(define (depth tree)
   (cond
      [(pair? tree)
       (+ 1 (max (depth (cadr tree))
                 (depth (caddr tree))))]
      [else 0]))

长答案

问题在于您使用cadrcaddr,正如您在运行给定示例时所看到的那样:

Example of Error

实际错误是:

cadr: contract violation
  expected: (cons/c any/c pair?)
  given: 2

这是因为您只检查empty?,仅在给出空列表时返回#t。像2这样的数字是 NOT 一个空列表,所以它返回#f,然后移动到第二个案例,在那里你试图获取一个空列表的cadr。显然这会失败。

检查某些内容是否为pair?可以获得您想要的实际案例。

一般来说,退一步并实际考虑你正在遍历的数据类型会更好。

例如,我可以写出:

Tree = (Cons LeftNode RightNode)
     | Number

考虑到这一点,更容易看到carcdr将直接访问您的孩子。

(car (Cons LeftNode RightNode)) => LeftNode

(cdr (Cons LeftNode RightNode)) => RightNode

显然,carcdr的数字将会出错。

从这里可以很明显地定义你的深度函数

(define (depth tree)
   (cond
      [(pair? tree)
       (+ 1 (max (depth (car tree))
                 (depth (cdr tree))))]
      [else 0]))

请注意,我使用pair?代替empty?。如果您真的想了解这里发生了什么,我强烈建议您查看How To Design Programs,它会带您完成我在这里以更慢(更清洁)的方式使用的设计配方步骤。

如果您愿意,您甚至可以将此想法扩展为包含具有3个或4个子节点的树:

Tree = (Listof Tree Tree Tree)
     | (Listof Tree Tree Tree Tree)
     | Number

鉴于此,您能为具有任意数量的子树节点的树找出粗略的数据类型吗?