Racket实现1、2欧元兑换为10、20欧分的代码修改问题
原代码问题分析
- 硬编码了仅判断凑200欧分的逻辑,无法适配100欧分(1欧元)的兑换需求,
<200直接返回0的判断也直接阻断了1欧元兑换的计算 - 递归逻辑错误:当前实现是「每种面额仅可使用1次」,处理完当前面额就直接丢弃,不符合10、20欧分可重复使用的兑换规则
- 边界条件逻辑混乱,硬币面额用完、余额为负的判断顺序和逻辑有误,会漏算合法组合
核心修改点
- 移除硬编码的200欧分判断,把目标兑换金额作为可传入参数,适配2欧元(200欧分)、1欧元(100欧分)两种兑换场景
- 调整递归逻辑:如果使用当前面额的硬币,保留当前面额在可用列表里,允许重复使用
- 修正边界条件:
- 余额为0时,说明找到1种合法兑换方式,返回1
- 余额小于0时,组合非法,返回0
- 可用面额为空时,无法继续兑换,返回0
- 若需要限制总共仅可兑换1次2欧元、1次1欧元,在外部维护两个标记位,兑换完成后置为不可用即可,不需要修改核心兑换逻辑
修改后可运行代码
;; 计算兑换方式数量版本 (define (count-change target coins) (cond [(= target 0) 1] [(< target 0) 0] [(empty? coins) 0] [else (+ (count-change (- target (first coins)) coins) ; 使用当前面额,保留该面额可重复调用 (count-change target (rest coins)))])) ; 不使用当前面额,切换到下一种面额 ;; 测试:2欧元(200欧分)兑换 (display "2欧元兑换的合法组合数:") (println (count-change 200 '(20 10))) ;; 测试:1欧元(100欧分)兑换 (display "1欧元兑换的合法组合数:") (println (count-change 100 '(20 10))) ;; 可选:输出所有具体兑换组合的版本 (define (list-change target coins) (cond [(= target 0) '(())] [(< target 0) '()] [(empty? coins) '()] [else (append (map (lambda (lst) (cons (first coins) lst)) (list-change (- target (first coins)) coins)) (list-change target (rest coins)))])) ;; 调用示例:输出1欧元的所有兑换组合 ;; (println (list-change 100 '(20 10)))
运行结果说明
- 2欧元兑换共有11种合法组合
- 1欧元兑换共有6种合法组合
内容的提问来源于stack exchange,提问作者Andra Botean
相关产品推荐
相关产品推荐

