SICP练习2.19 - 如何扩展这个?

时间:2013-01-30 04:25:22

标签: functional-programming lisp scheme sicp

我正在通过SICP探索函数式编程,我想知道如何扩展练习2.19以做一些更有用的事情(这似乎需要副作用)。

该练习涉及一个程序,该程序计算一个给定硬币面额列表的给定数量(以便士为单位)可以改变的方式。解决方案非常简单(cc代表“计数更改”):

(define (cc amount coin-values)
  (cond ((= amount 0) 1)
        ((or (< amount 0) (no-more? coin-values)) 0)
        (else
         (+ (cc amount
                (except-first-denomination coin-values))
            (cc (- amount
                   (first-denomination coin-values))
                coin-values)))))

(define (first-denomination coinTypes) (car coinTypes))
(define (except-first-denomination coinTypes) (cdr coinTypes))
(define (no-more? coinTypes) (null? coinTypes))

您可以看到相关的SICP部分here,如果上述情况不明确,则链接到算法说明。

我首先想知道硬币的实际组合构成每种方式进行更改所以我编写了自己的版本,将每个解决方案打印为列表:

(define (count-change amount coinTypes)
    (define (cc amount coinTypes currChangeList)
        (cond ((= amount 0) 
                    (display (reverse currChangeList)) 
                    (newline) 
                    1)
              ((or (negative? amount) (null? coinTypes)) 
                    0)
              (else (+ (cc amount (cdr coinTypes) currChangeList)
                       (cc (- amount (car coinTypes)) coinTypes (cons (car coinTypes) currChangeList))))))
    (cc amount coinTypes ()))

所以这就是我被困住的地方:我想修改我的方法,以便不是返回一个整数结果=#方法进行更改,而只是在计算过程中打印每一条路,我希望它返回一个列表解决方案(列表清单,其长度=进行更改的方式)。但是,我不知道如何实现这一目标。在命令式/ OO语言中很容易做到,但我无法弄清楚如何在功能上做到这一点。

有人知道如何实现这个目标吗?对于经验丰富的功能编码器来说,这似乎应该是一件非常容易的事情。请帮助满足我的好奇心,并为自己创造一些编码业力:)

由于

1 个答案:

答案 0 :(得分:0)

(define (count-change amount coinTypes)
    (define (cc amount coinTypes currChangeList)
        (cond ((= amount 0) 
               (list (reverse currChangeList)))
              ((or (negative? amount) (null? coinTypes)) 
               '())
              (else
                (append
                   (cc amount (cdr coinTypes) currChangeList)
                   (cc (- amount (car coinTypes))
                       coinTypes
                       (cons (car coinTypes) currChangeList))))))
    (cc amount coinTypes '()))