このコードがあります
(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))))))
これで、リストを 1 回反転するだけで済み、効率が大幅に向上します。コードをきれいにするために、 の定義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
toに変更しましx
たが、実際にはこれを行う必要はありません。そのままにしておいても同様に機能しますls
。これは、あなたが手に入れようとしているのと同じくらいコンパクトです。