Scheme 调试我的校验和函数

Scheme 调试我的校验和函数,scheme,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。有人能帮我们调试吗?如前所述,此函数将返回 5 * 6 + 4 * 4 + 3 * 5 + 2 * 6 + 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。有人能帮我们调试吗?

如前所述,此函数将返回

5 * 6 + 4 * 4 + 3 * 5 + 2 * 6 + 1 * 7 = 80
这是因为在每个阶段,它都会获取反转列表的第一个元素(即列表的最后一个元素)并将其乘以列表长度,然后将其添加到调用反转列表上的
校验和-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
的定义中考虑
chksum-helper
的定义,如下所示:

(define (chksum ls)
  (define (chksum-helper x)
    (cond
      ((null? x) 0)
      (else (+ (* (length x) (car x))
               (chksum-helper (cdr x))))))
  (chksum-helper (reverse ls)))

为了避免混淆,我将参数从
ls
重命名为
chksum-helper
,改为
x
,但实际上您不必这样做-如果将其保留为
ls
,效果也一样。这是你想要的最紧凑的东西。

那么这个呢?(定义(校验和-2 ls)(let([x(反向ls)])(cond[(null?ls)0][else(+(*(长度ls)(car x))(校验和-2(cdr ls)))))当我们这样做时,我们的答案是90:\对不起,是我的错。请参阅更正的版本。事实上,我会更新一下这个答案,所以请继续查看。谢谢!它仍然给我们90分,我们从美国东部时间晚上11点到现在凌晨4:30就一直在做这个:\记住,你可能不会进入你目前想要进入的领域。如果你真的到了那里,当你到达那里的时候,他们甚至可能没有使用Java。你唯一能指望的就是改变。