在球拍中,我创建了一个用于在列表中查找最大值的函数,但是我的一些测试用例无法正常工作,为什么其中一些无法正常工作?

时间:2019-07-16 22:28:29

标签: list struct scheme racket

我创建了一个函数,该函数可以在列表中找到最大值,该函数应该可以正常工作,但是我的代码可能在某个地方出错。

这是我的代码,

(define-struct ls (first rest))
;; a Ls is either
;; '(), or
;; (make-ls first rest) where first is an Int and rest is a Ls.

(define (ls-max L)
  (cond
    [(empty? L) 0]
    [(empty? (ls-rest L)) (ls-first L)]
    [(< (ls-first L) (ls-first (ls-rest L))) (ls-max (ls-rest L))]))

这是我制作的三个正确的测试用例,它们表明我的代码正在工作。

(check-expect (ls-max (make-ls 2 (make-ls 4 '()))) 4)
(check-expect (ls-max (make-ls 3 (make-ls 10 '()))) 10)
(check-expect (ls-max (make-ls 12 (make-ls 23 (make-ls 33 '())))) 33)

您可以看到我说第一次测试的最大值是4,这是正确的;第二次测试的最大值是10,这是正确的,而第三次测试的最大值是33,是正确的。 >

但是,对于其他4种情况,我的测试都是不正确的,我也不知道为什么。如果代码正确,那么为什么只有前三个测试正确,而后四个测试却不正确;如果我的代码不正确,为什么前三个测试可以正常工作。我很困惑为什么我的代码会发生这种情况

(check-expect (ls-max (make-ls 22 (make-ls -32 (make-ls 12 (make-ls -3 '()))))) 22)
(check-expect (ls-max (make-ls -2 (make-ls -23 (make-ls 0 (make-ls -1 '()))))) 0)
(check-expect (ls-max (make-ls 10 (make-ls 9 (make-ls 222 (make-ls 223 '()))))) 223)
(check-expect (ls-max (make-ls 2 (make-ls 3 (make-ls 4 (make-ls 7 (make-ls -1 (make-ls 72
            (make-ls 22 (make-ls 90 '()))))))))) 90)

从本质上讲,我想知道为什么我的前三个测试正确,而后四个测试却不正确。

我刚刚意识到我的代码中肯定有一个错误。前三个测试只起作用,因为最大值是列表中的最后一个值,现在我不确定代码中的错误。

1 个答案:

答案 0 :(得分:2)

要在列表中查找最大值,仅将一个元素与下一个元素进行比较是不够的:最大值可能在列表中领先,因此您需要递归比较当前元素与最大值在列表的其余部分中,如下所示:

(define (ls-max L)
  (cond
    ; I'd rather return #f for the empty list base case
    [(empty? L) #f]
    ; Base case: single-element list
    [(empty? (ls-rest L)) (ls-first L)]
    ; If current element is the max, return it
    [(>= (ls-first L) (ls-max (ls-rest L))) (ls-first L)]
    ; Otherwise the max is in the rest of the list. As an
    ; optimization we could use a `let` to avoid making the
    ; recursive call twice, left as an exercise for the reader
    [else (ls-max (ls-rest L))]))