【问题标题】:Racket Contract Violation (Max Recursion Function)违反球拍合约(最大递归函数)
【发布时间】:2018-06-07 23:22:18
【问题描述】:

学习一些计划/球拍,所以给我一些余地。

当前在不使用内置 max() 函数的情况下尝试在给定列表时查找最大值。

当前代码:

#lang racket
(provide max-num)
(define (max-num lst)
  (define (helper lst max)
    (displayln lst)
    (displayln max)
    (displayln " ")
    (when (null? max) ; first run
        (helper (cdr lst) (car lst)))
    (if (null? lst)
        max ; then end
        (if (> (car lst) max) ; else compare
            (helper (cdr lst) (car lst)) ; then update max
            (helper (cdr lst) max)))) ; else keep max
  (if (null? lst)
      #f ; then Error
      (helper lst '())) ; else run helper
  )

(max-num '())
(max-num '(1 5 2 4 3))

通过 DrRacket 输出:

据我所知,displayln 输出告诉我我在正确的轨道上。然而,它最终以违反合同而告终吗?错误而不是返回最大值。

我猜测 (if (null?lst)) 不想在最后返回“max”,而是尽管列表为空,但仍会推向 else 分支。我已经环顾四周并调试了大约一个小时,但无济于事。任何帮助将不胜感激。

【问题讨论】:

    标签: scheme max racket contract


    【解决方案1】:

    当你这样做时,你必须知道:

    (when test
      do-something)
    do-something-else
    

    无论test 是否为真,它总是do-something-else。所以发生的事情是第一轮maxnull? 并且它确实是(helper (cdr lst) (car lst))) 并返回了答案。然后它丢弃该答案并继续ifmaxnull?,当它执行(> (car lst) max) 时它最终失败,因为null? 不是数字。错误消息说它需要一个real?,但它得到了初始值'()

    因此,为了提示您,除了本地定义之外,您还应该有 一个表达式,例如。

    (if test1
        result1
        (if test2
            result2
            alternative2))
    

    (cond (test1 result1)
          (test2 result2)
          (else alternative2))
    

    当然,既然你知道参数不是null?,你可以只调用(helper (cdr lst) (car lst)),而不是传递空列表并完全删除whenwhenunless 是为了副作用,而不是为了好的功能方案风格。

    【讨论】:

    • 天哪,非常感谢。得到它的工作。希望 Scheme/Racket 能帮助我在 OOP 中很少使用的可怕递归技能。
    猜你喜欢
    • 2016-08-30
    • 2015-04-17
    • 1970-01-01
    • 2020-10-11
    • 1970-01-01
    • 2012-09-30
    • 1970-01-01
    • 2012-10-07
    • 2013-09-24
    相关资源
    最近更新 更多