问题描述
我想知道1美元可以用1、5、10、20、50美分表示的情况。
例如,count(100,[50,25])
是:
因为 50 * 1 + 25 * 2,it = 3:int is printed.
但是,在我的代码中,只打印了列表的前部,所以即使我 count (100,25])
,it = 2:int is printed.
换句话说,我的代码没有利用整个列表。
我该如何解决这个问题?
SML 硬币计数功能:
fun count(x,[]) = 0
| count (x,y::ys) =
let val cnt = 0
in if y*2 = x then cnt+2
else if y*4 = x then cnt + 4
else if y*10 = x then cnt + 10
else if y*10 = x then cnt + 10
else if y*20 = x then cnt + 20
else count(x-y,ys)
end;
解决方法
考虑评估 count (100,[50,25])
的测试表达式时会发生什么。
cnt
是 0
,y
是 50
,而 ys
是 [25]
。
y
乘以 2
does 等于 100
,因此它返回 cnt+2
,即 2
。没有进一步的事情发生。
说到递归,请记住,函数的参数列表是您的通信方式。似乎 cnt
应该作为参数传递,以便您可以在递归调用之间更新它。
使用 count(x,[]) = 0
,您已经有了一个可以停止递归的退出点。
编辑:根据评论,您似乎正在尝试计算列表中每个值进入值 x
的次数。
所以你的递归函数的最终结果不是一个整数。这是一个整数列表。或者更好的是,包含要查找的值的元组,以及它进入 x
的次数。
所以如果列表为空,结果很明显。
fun count(x,[]) = []
这是一个空列表。否则,我们需要将某些内容附加到列表中。
fun count(x,[]) = []
| count(x,y::ys) =
(y,x div y) :: count(x,ys)
当然,我们也有像 map
这样的函数,基本上可以为我们做这些。
fun count(x,lst) = List.map (fn y => (y,x div y)) lst