私は最良の方法は、事前計算することではなく、入れ子にすることではないと感じます。我々はゼロのいずれかでテストベースケースを見て:
(mystery 0 2) ; ==> 2
(nystery 3 0) ; ==> 3
は、このように少なくとも一つの引数がゼロであるたびに、それは他の引数を返します。我々はベースケースは、常に私たちにはない、他の値を返します知っているので
(mystery 1 3) ; ==
(+ 2 (mystery 0 2)) ; == (we switch known value)
(+ 2 2)
; ==> 4
(mystery 4 1) ; == (we substitute with the expression)
(+ 2 (mystery 3 0)) ; == (we switch known value)
(+ 2 3)
; ==> 5
:ゼロ以外の値で試してみて、あなたはちょうどその結果でそれを切り替える前に、我々はすでにやっている値を参照してください秒を覚えていますそれを事前に計算する必要があります。ここでは、それを行うことがあります:
(mystery 3 9) ; == (we substitute with the expression)
(+ 2 (mystery 2 8) ; == (we substitute with the expression)
(+ 2 (+ 2 (mystery 1 7))) ; == (we substitute with the expression)
(+ 2 (+ 2 (+ 2 (mystery 0 6))) ; == (we substitute with the expression, n, which is 6)
(+ 2 (+ 2 (+ 2 6))) ; == (we substitute (+ 2 6))
(+ 2 (+ 2 8)) ; == (we substitute (+ 2 8))
(+ 2 10) ; == (we substitute (+ 2 10)
; ==> 12
私たちは一般化することができます。 n
とm
の最低値は、再帰がいつ終了するかを決定します。各ステップで2を加えて再帰します。
(define (double-min n m)
(let ((vmin (min n m))
(vmax (max n m)))
(+ (* 2 vmin) (- vmax vmin))))
再び2*m+(n-m) = m+m+(n-m) = m+n
ありがとう、それはそれをはるかに明確にする – bgb102
この回答は間違っており、それは難しいです。 '(謎0)'は ' 'でなく、' 0'でなければなりません。 'mystery'は質問のタイトルが意味するように追加を実装し、" double-min "を実装しません。 –
jerry
@jerryミステリーはOPコードのように、**追加を実装していません。 「n」または「m」のいずれかがゼロの場合、結果はゼロになります。デフォルトの場合は2を加算し、両方の引数を1つ減らして再帰の結果を返します。したがって、基本ケースは、2つのうちの最小のものがゼロであるときであり、関数がその最小の引数の2倍を計算する。したがって、 '(* 2(min n m))'となります。代入にあらかじめ計算された値を使用することは、純粋な再帰関数について理解する最も簡単な方法です。 – Sylwester