SICP 习题 1.14要求计算出过程count-change的增长阶。count-change是书中1.2.2节讲解的用于计算零钱找换方案的过程。
要解答习题1.14,首先你需要理解count-change的工作方式,要理解count-change的工作方式,最好是自己去实现一遍count-change。
为了避免自己直接抄书中的代码,我决定自己实现一遍用来找换人民币的的“count-change”。事实上,我在看完并理解count-change的代码后,当我去实现人民币版的“count-change”时,我就强制自己不再回去看“count-change”的代码,保证自己有更多的主动思考。
有意思的是,当我实现完了回去看书上的代码,发现两者还是有挺大的区别,虽然算法是一样的,结果也都正确的。
首先我们得有个过程遍历各种零钱,我为了简化程序,只做了“元”的找换,“分”和“角”就略过了。
遍历各种零钱的过程如下,就是遍历“1元”,“2元”,“5元”,“10元”,“20元”,“50元”,“100元”这几种零钱。
这里就和书上有点差别,书上是记录现在还可以使用几种零钱,根据可以使用的零钱种类数量返回其中最大面值的金额。
我是简单粗暴地从最小面值遍历到最大面值。
(define (RMB-Change-Next-Kind change-kind)
(cond ((= change-kind 1) 2)
((= change-kind 2) 5)
((= change-kind 5) 10)
((= change-kind 10) 20)
((= change-kind 20) 50)
((= change-kind 50) 100)
(else 0)))
书中讲到的找换零钱的方法基于以下基本思路:
比如我们需要将100块的人民币找换成零钱,有几种找换方式?可以简单分为两种:有使用1块面额的,和没有使用1块面额的。
对于有使用1块面额的,把这一块钱去掉,剩99块,我们又可以继续看99块有几种找换方式。找到99块的所有找换方式,在加上现在这里去掉的1块钱,就是100块找换方式中有使用1块的所有找换方式。
对于没有使用1块面额的,我们就需要看看100块找成其它面额(不包含1块)的找换方式。
然后将上面两种类型的数量加起来就是100块的所有找换方式。