合同违规

时间:2018-02-13 21:18:40

标签: algorithm scheme racket r5rs

我正在尝试编写一个递归函数来测试输入的整数中的数字是否按升序排列。当我运行我的代码时,我收到合同违规错误。

(define (rising-numbers n)
  (if(zero? (truncate n))
     (modulo n 10)
     (> (modulo n 10) (rising-numbers (quotient n 10)))))

(rising-numbers 123)

这是我得到的错误:

>: contract violation
expected: real?
given: #t
argument position: 2nd
other arguments...:

2 个答案:

答案 0 :(得分:2)

只要查看你的函数,我看到你的函数在(zero? (truncate n))时返回一个数字,如果它是假的,则返回布尔。原因是>始终返回布尔值#t#f。虽然返回不同类型是该语言的一个特性,但它在运行时变得不可预测时通常会出错。

根据错误消息,您已将布尔值作为>的参数之一。所以问题在于你使用>唯一的地方:

(> (modulo n 10) (rising-numbers (quotient n 10)))

在这里你做(rising-numbers (quotient n 10))作为数字参数但是因为我们已经在第一部分中建立了这可以返回一个布尔值,你不能将这个值用作>中的第二个参数。

那你怎么做得对。好。一如既往,我们有基本情况:

(rising-numbers 2); ==> #t

现在默认情况应该这样做:

(rising-numbers 123)                             ; ==
(and (<= 2 3) (rising-numbers 12))               ; ==
(and (<= 2 3) (and (<= 1 2) (rising-numbers 1))) ; ==
(and #t #t)                                      ; ==> #t

在这种情况下,rising-numbers永远不会返回数字,总是布尔值,您需要检查每一步中的当前值和下一个值。事实上,你得到一个基本案例和当前和下一个数字之间的n-1比较。

答案 1 :(得分:1)

这个问题是步进器的完美。确保语言级别为“Beginning Student”,除了您在定义窗口中粘贴的代码外,不要输入任何内容,然后单击“step”。我想你会很快看到问题!