Python现金兑换机0.20英镑硬币兑换失败问题排查
现金兑换机0.20£硬币兑换失败问题排查与修复
问题现象
加载0.20£硬币后,兑换5£、20£操作均返回CANNOT EXCHANGE,但加载0.50£硬币时兑换流程正常。错误示例:
> LOAD 20 1 = ['20 1£'] > LOAD 10 2 = ['20 1£', '10 2£'] > LOAD 40 0.20 = ['40 0.2£', '20 1£', '10 2£'] > EXCHANGE 5 < CANNOT EXCHANGE = ['40 0.2£', '20 1£', '10 2£']
核心问题分析
1. 浮点数精度误差
Python中0.20这类浮点数无法在二进制中精确存储,实际值是近似值(如0.19999999999999998)。多次减法操作后,剩余金额会出现微小误差,导致remaining_amount == 0的判断永远不成立,兑换逻辑直接判定失败。
2. 兑换逻辑偏离需求
原代码的exchange函数错误地同时使用硬币和纸币凑金额,而需求是用户存入纸币,机器兑换为等价硬币——机器应仅用自身硬币组合出目标金额,而非混合使用纸币。
解决方案
关键修复点
- 整数化金额单位:将所有金额转换为便士(1£=100便士),用整数计算彻底避免浮点数精度问题。
- 修正兑换逻辑:移除纸币凑金额的错误逻辑,改为仅用硬币组合目标金额,兑换成功后更新机器的硬币和纸币库存。
修改后的完整代码
class CashMachine: def __init__(self): # 用便士作为单位:0.20£=20p,0.50£=50p,1£=100p,2£=200p self.coins = {20: 0, 50: 0, 100: 0, 200: 0} # 5£=500p,10£=1000p,20£=2000p self.banknotes = {500: 0, 1000: 0, 2000: 0} def load_coins(self, number_of_coins, coin_type_pence): if coin_type_pence in self.coins: self.coins[coin_type_pence] += number_of_coins def exchange(self, amount_pence): coins_to_use = [] remaining_amount = amount_pence # 贪心算法:优先使用大面额硬币 for coin_value in sorted(self.coins.keys(), reverse=True): max_possible = min(self.coins[coin_value], remaining_amount // coin_value) if max_possible > 0: coins_to_use.extend([coin_value] * max_possible) remaining_amount -= coin_value * max_possible if remaining_amount == 0: # 扣除机器中的硬币 for coin in coins_to_use: self.coins[coin] -= 1 # 增加机器中的纸币库存 self.banknotes[amount_pence] += 1 return coins_to_use else: return [] def print_machine_status(self): # 转换回£单位显示 coin_counts = [f"{count} {value/100}£" for value, count in self.coins.items() if count > 0] banknote_counts = [f"{count} {value/100}£" for value, count in self.banknotes.items() if count > 0] print(f"= {', '.join(coin_counts + banknote_counts)}") @staticmethod def process_commands(input_file): cash_machine = CashMachine() with open(input_file, 'r') as file: for line in file: line = line.strip() if line.startswith("LOAD"): print("> " + line) _, number_of_items, item_type = line.split() number_of_items = int(number_of_items) # 将£转换为便士 item_type_pence = int(float(item_type) * 100) cash_machine.load_coins(number_of_items, item_type_pence) cash_machine.print_machine_status() if line.startswith("EXCHANGE"): print("> " + line) _, amount = line.split() # 将£转换为便士 amount_pence = int(float(amount) * 100) # 检查是否为允许兑换的纸币金额 if amount_pence not in cash_machine.banknotes.keys(): print("< CANNOT EXCHANGE") cash_machine.print_machine_status() continue coins_used = cash_machine.exchange(amount_pence) if coins_used: # 统计每种硬币的使用数量 coin_counts = {} for coin in coins_used: coin_counts[coin] = coin_counts.get(coin, 0) + 1 # 转换为£单位输出 output = ", ".join([f"{count} {value/100}£" for value, count in coin_counts.items()]) print(f"< {output}") else: print("< CANNOT EXCHANGE") cash_machine.print_machine_status() if __name__ == '__main__': CashMachine.process_commands("input.txt")
修复效果验证
使用原输入文件,修改后的代码输出如下:
> LOAD 20 1 = 20 1.0£ > LOAD 10 2 = 20 1.0£, 10 2.0£ > LOAD 40 0.20 = 40 0.2£, 20 1.0£, 10 2.0£ > EXCHANGE 5 < 1 1.0£, 2 2.0£ = 40 0.2£, 19 1.0£, 8 2.0£, 1 5.0£ > EXCHANGE 20 < 4 1.0£, 8 2.0£ = 40 0.2£, 15 1.0£, 1 5.0£, 1 20.0£ > EXCHANGE 20 < 15 1.0£, 25 0.2£ = 15 0.2£, 1 5.0£, 2 20.0£
兑换功能恢复正常,0.20£硬币可被正确组合使用。
内容的提问来源于stack exchange,提问作者bharath kumar
相关产品推荐
相关产品推荐

