私の SML マニュアルで、特定の変更に必要な特定の種類のコインの数を計算する次の関数を見たことがあります。たとえばchange [5,2] 16 =[5,5,2,2,2]
、2 枚の 5 コインと 3 枚の 2 コインがあると、16 になります。
次のコードは、バックトラッキング アプローチです。
exception Change;
fun change _ 0 = nil|
change nil _ = raise Change|
change (coin::coins)=
if coin>amt then change coins amt
else (coin:: change (coin::coins) (amt-coin))
handle Change=> change coins amt;
それは機能しますが、正確にはわかりません。バックトラッキングとは何かは知っていますが、この特定の機能を理解していません。
私がこれまでに理解したこと:amt
が 0 の場合、変更が計算され、最終的なリストにコンスされるものがないことを意味します。
「-list」にコインがもうない場合は、coin
1 ステップ戻る必要があります。
これは私が迷っているところです: 例外を発生させることは、私たちが戻るのにどのように役立ちますか?
change
私が見たように、ハンドラーは関数を呼び出そうとしますが、 " coins
" パラメーターはnil
? したがって、無限ループに入りますか?なぜ「戻る」のですか?
最後の節は私には明らかです。coin-value が釣り銭の残りの金額よりも大きい場合、残りのコインを使用して釣り銭を構築します。残りの量よりも小さい場合は、結果リストにコンスします。