我们有这个代码
(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.任何人都可以帮我们调试吗?
答案 0 :(得分:0)
如上所述,此函数将返回
5 * 6 + 4 * 4 + 3 * 5 + 2 * 6 + 1 * 7 = 80
这是因为在每个阶段,它采用反向列表的第一个元素(即列表的最后一个元素)并将其乘以列表长度,并将其添加到调用checksum-2
的结果中颠倒列表。然后列表再次反向,因此要添加的下一个元素是最初位于列表 front 的元素(在这种情况下为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
的参数从ls
重命名为x
以防止混淆,但您实际上并不需要这样做 - 如果您离开它,它也可以正常工作为ls
。这就像你要得到它一样紧凑。