私が変換する一般的な方法見つけたようだ任意の末尾再帰に再帰的な手順を:
- 追加の「結果」パラメーターを使用して、ヘルパーサブプロシージャを定義します。
- プロシージャの戻り値に適用されるものをそのパラメータに適用します。
- このヘルパープロシージャを呼び出して開始します。「結果」パラメーターの初期値は、再帰プロセスの終了点の値であるため、結果の反復プロセスは、再帰プロセスが縮小し始めるところから始まります。
たとえば、変換する元の再帰的手順は次のとおりです(SICP演習1.17)。
(define (fast-multiply a b)
(define (double num)
(* num 2))
(define (half num)
(/ num 2))
(cond ((= b 0) 0)
((even? b) (double (fast-multiply a (half b))))
(else (+ (fast-multiply a (- b 1)) a))))
変換された末尾再帰手続き(SICP演習1.18)は次のとおりです。
(define (fast-multiply a b)
(define (double n)
(* n 2))
(define (half n)
(/ n 2))
(define (multi-iter a b product)
(cond ((= b 0) product)
((even? b) (multi-iter a (half b) (double product)))
(else (multi-iter a (- b 1) (+ product a)))))
(multi-iter a b 0))
誰かがこれを証明または反証できますか?
b
2のべき乗を選択すると、最初はproduct
0に設定するのは適切ではないことがわかります。しかし、1に変更しても、b
奇数の場合は機能しません。たぶん、2つの異なるアキュムレータパラメータが必要ですか?