我在我的 SML 手册中看到了以下函数,该函数计算特定更改需要多少特定种类的硬币。例如change [5,2] 16 =[5,5,2,2,2]
,因为有两个 5 硬币和三个 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,这意味着我们的变化是计算出来的,在最终列表中没有什么可以被 cons'd 的。
如果我们的“-list”中没有更多的硬币coin
,我们需要后退一步。
这就是我迷失的地方:引发异常究竟如何帮助我们返回?
如我所见,处理程序尝试调用该change
函数,但“ coins
”参数不应该是nil
吗?因此进入无限循环?为什么会“回去”?
最后一个条款对我来说非常明显:如果硬币价值大于剩余的找零数量,我们使用剩余的硬币来构建找零。如果它小于剩余的数量,我们将其添加到结果列表中。