-1

我们有这个代码

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

4

1 回答 1

0

如所写,此函数将返回

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-helperfrom lstox以防止混淆,但您实际上不必这样做 - 如果您将其保留为ls. 这与您将要获得的一样紧凑。

于 2012-09-26T08:06:27.960 回答