我修改了SICP中count-change
函数的代码,以便在函数递归时它将显示一对。这对的形式是"(cc a k)" -> "(cc a (- k 1))"
或"(cc a k)" -> "(cc (- a (d k)) k)"
,我的目标是建立一个DOT文件来显示使用GraphViz的树状递归。如何使用方案宏来显示评估树
下面是一个例子的图像,从下面的代码生成:
这里的方案的代码:
; Count Change
(define (count-change amount)
(cc amount 5))
(define (cc amount kinds-of-coins)
(begin
(cond ((= amount 0) 1)
((or (< amount 0) (= kinds-of-coins 0)) 0)
(else (+
(begin
(display "\"")
(display `(cc ,amount ,kinds-of-coins))
(display "\"")
(display " -> ")
(display "\"")
(display `(cc ,amount ,(- kinds-of-coins 1)))
(display "\"")
(display "\n")
(cc amount (- kinds-of-coins 1))
)
(begin
(display "\"")
(display `(cc ,amount ,kinds-of-coins))
(display "\"")
(display " -> ")
(display "\"")
(display `(cc ,(- amount (first-denomination kinds-of-coins)) ,kinds-of-coins))
(display "\"")
(display "\n")
(cc (- amount (first-denomination kinds-of-coins)) kinds-of-coins)
)
)
))))
; first-denomination takes the number of kinds of coins and returns the denomination of the first kind
(define (first-denomination kinds-of-coins)
(cond ((= kinds-of-coins 1) 1)
((= kinds-of-coins 2) 5)
((= kinds-of-coins 3) 10)
((= kinds-of-coins 4) 25)
((= kinds-of-coins 5) 50)))
(count-change 11)
原始代码是here。
我已阅读关于方案宏,我认为他们可以解决这个问题,允许我在begin
语句中用'wrap'调用(cc。)语句来显示递归时正在发生的事情。
这怎么可以用Scheme宏来完成?
注意:我知道我的图像是不准确的,我需要找到一种使节点不同的方法,以便图形是一棵树,而不仅仅是一个DAG。但是,这超出了这个问题的范围。
对于实现,我使用MIT/GNU计划。这比我有的更好,我喜欢打印是在它自己的功能。实际上,这可以通用化,以便'cc'是一个通用函数,这样我可以在其他函数上重用它! – tlehman 2013-02-11 05:49:03
我没有使用本地函数,但是我做了类似于你所建议的[这里](https://github.com/tlehman/sicp-exercises/blob/master/count-change-verbose.scm) 。我正在努力使它独立于函数的arity。 – tlehman 2013-02-11 06:16:14
我通过使用节点的标签来解决这个问题,因此'rrllr'会向右,左,左,右移动。 [详情和图片在这里](http://tobilehman.com/blog/2013/04/07/visualization-of-sicp-exercise-1-dot-14/) – tlehman 2013-05-15 03:08:07