-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))))))

これで、リストを 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-helperfrom lstoに変更しましxたが、実際にはこれを行う必要はありません。そのままにしておいても同様に機能しますls。これは、あなたが手に入れようとしているのと同じくらいコンパクトです。

于 2012-09-26T08:06:27.960 に答える