递归实现精确购笔金额判断:修复返回None问题及终止逻辑优化
问题场景与问题点
给定单价为[7,9,11]的笔,需要实现Python函数can_i_buy(x),判断是否能凑出精确金额x(例如x=23时,1支9元+2支7元可凑出,返回True)。
用户尝试用递归实现,但存在两个问题:
- 代码存在重复逻辑:硬编码处理每个价格的递归调用,扩展性差
- 递归终止条件不完善:输入x=24时返回None,预期应返回False,因为所有分支尝试后都无法凑出金额,且x<0时未返回明确的布尔值
原递归代码
def can_i_buy(x): # 23 return helper(x, [7,9,11]) def helper(x, lst): if x == 0: return True if x < 0: return take_1 = helper(x - lst[0], lst) if take_1 == True: return take_1 take_2 = helper(x - lst[1], lst) if take_2 == True: return take_2 take_3 = helper(x - lst[2], lst) if take_3 == True: return take_3
测试代码与输出
测试代码:
print(can_i_buy(24)) print(can_i_buy(23)) print(can_i_buy(7)) print(can_i_buy(14))
输出:
None True True True
修复与优化后的代码
def can_i_buy(x): return helper(x, [7, 9, 11]) def helper(x, prices): # 凑出目标金额,返回True if x == 0: return True # 金额不足,无法凑出,返回False if x < 0: return False # 遍历所有价格,递归尝试扣除当前价格后的金额是否能凑出 for price in prices: if helper(x - price, prices): return True # 所有价格尝试后都无法凑出,返回False return False
优化说明
- 完善终止条件:将
x < 0时的返回改为False,避免返回None;同时在所有递归分支尝试失败后,明确返回False,确保函数始终返回布尔值 - 消除重复逻辑:用循环遍历价格列表替代硬编码的三个分支,代码更简洁,且如果价格列表变更(比如新增笔的单价),无需修改递归逻辑
- 测试验证:运行原测试代码,输出变为:
完全符合预期结果False True True True
内容的提问来源于stack exchange,提问作者LearningToCode
相关产品推荐
相关产品推荐

