方案:列出使用列表进行10次更改的所有方法

时间:2016-04-24 22:51:37

标签: scheme

目标:总计:10           denoms:(10 5 1)           返回((10)(5 5)(5 1 1 1 1 1)(1 1 1 1 1 1 1 1 1 1))

我的代码:

(define (changes-list total denoms)

    (cond

    ((null? denoms) nil )

    ((= total 0 ))

    ((> (car denoms) total) (changes-list total (cdr denoms)))

    (else

      (if (= total (car denoms)) (cons (list (car denoms)) (changes-list total (cdr denoms)))
      (append (cons-all (car denoms) (changes-list (- total (car denoms)) denoms))))
    )  )  )

~~~~~~ 我的代码现在输出的是:((10)(5 5)(5 1 1 1 1 1)) 我认为问题可能在于cond,当我调用change-list on(cdr denoms)并且更改为空时退出并退出但我不知道如何解决这个问题。非常感谢所有帮助!!

2 个答案:

答案 0 :(得分:0)

假设有以下两个条件(否则你应该检查参数):

  1. total始终是非负面的,
  2. denoms按递减顺序排序,最后一个元素始终为1
  3. 这是一个可能的解决方案:

    (define (cons-all x lst)
      (map (lambda (l) (cons x l)) lst))
    
    (define (repeat n x)
      (if (= n 0)
          '()
          (cons x (repeat (- n 1) x))))
    
    (define (changes-list total denoms)
      (cond ((= total 0) '(()))
            ((null? (cdr denoms)) (list (repeat total (car denoms))))
            ((< total (car denoms)) (changes-list total (cdr denoms)))
            (else (append (cons-all (car denoms) (changes-list (- total (car denoms)) denoms))
                          (changes-list total (cdr denoms))))))
    
    (changes-list '6 (2 1)) ; => ((2 2 2) (2 2 1 1) (2 1 1 1 1) (1 1 1 1 1 1))
    

答案 1 :(得分:0)

当尝试不同的路径并不是每个人都会产生有效的解决方案时,我喜欢使用path列表来跟踪路径,而累加器acc只能保留成功的结果:< / p>

(define (changes-list total denoms)
  (let iter ((total total) (denoms denoms) (path '()) (acc '()))
    (cond
      ((= total 0) (cons (reverse path) acc)) ; the current path lead to a solution => keep path in accumulator
      ((or (< total 0) (null? denoms)) acc) ; discard path
      (else
       (let ((denom (car denoms))) ; first denomination
         (iter (- total denom)     ; (1) use first denomination
               denoms
               (cons denom path)
               (iter total         ; (2) drop first denomination
                     (cdr denoms)
                     path
                     acc)))))))

测试:

> (changes-list 10 '(10 5 1))
'((10) (5 5) (5 1 1 1 1 1) (1 1 1 1 1 1 1 1 1 1))
> (changes-list 6 '(2 1))
'((2 2 2) (2 2 1 1) (2 1 1 1 1) (1 1 1 1 1 1))