调试我的校验和功能

时间:2012-09-26 08:01:16

标签: scheme

我们有这个代码

(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.任何人都可以帮我们调试吗?

1 个答案:

答案 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。这就像你要得到它一样紧凑。