我创建了一个函数,该函数可以在列表中找到最大值,该函数应该可以正常工作,但是我的代码可能在某个地方出错。
这是我的代码,
(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)
从本质上讲,我想知道为什么我的前三个测试正确,而后四个测试却不正确。
我刚刚意识到我的代码中肯定有一个错误。前三个测试只起作用,因为最大值是列表中的最后一个值,现在我不确定代码中的错误。
答案 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))]))