我们有这个代码
(define (checksum-2 ls)
(let ([x (reverse ls)])
(cond
[(null? ls) 0]
[else (+ (* (length ls) (car x)) (checksum-2 (cdr x)))])))
它颠倒了这个列表
'(4 6 7 5 6)
假设返回 87 但它返回 80。任何人都可以帮助我们调试这个吗?
我们有这个代码
(define (checksum-2 ls)
(let ([x (reverse ls)])
(cond
[(null? ls) 0]
[else (+ (* (length ls) (car x)) (checksum-2 (cdr x)))])))
它颠倒了这个列表
'(4 6 7 5 6)
假设返回 87 但它返回 80。任何人都可以帮助我们调试这个吗?
如所写,此函数将返回
5 * 6 + 4 * 4 + 3 * 5 + 2 * 6 + 1 * 7 = 80
这是因为在每个阶段,它取反向列表的第一个元素(即列表的最后一个元素)并将其乘以列表长度,并将其添加到调用反向列表checksum-2
的结果中。然后列表再次反转,因此要添加的下一个元素是最初位于列表前面的元素(在这种情况下)。4
您要做的是将列表反转一次,然后从那时起使用反转的列表。为此,您可以使用辅助函数:
(define (chksum ls)
(chksum-helper (reverse ls)))
(define (chksum-helper ls)
(cond
((null? ls) 0)
(else (+ (* (length ls) (car ls))
(chksum-helper (cdr ls))))))
现在您只需将列表反转一次,这在效率上是一个巨大的胜利。要清理代码,您可以在 的定义中chksum-helper
分解 的定义chksum
,得到如下内容:
(define (chksum ls)
(define (chksum-helper x)
(cond
((null? x) 0)
(else (+ (* (length x) (car x))
(chksum-helper (cdr x))))))
(chksum-helper (reverse ls)))
我将参数重命名为chksum-helper
from ls
tox
以防止混淆,但您实际上不必这样做 - 如果您将其保留为ls
. 这与您将要获得的一样紧凑。