JS实现收银机找零逻辑时循环跳过面额元素的问题排查
收银机找零函数遍历跳面额问题排查
问题描述
编写目标为拆解找零金额到对应货币面额、返回找零完成后更新的收银机余额的函数,当前仅在收银机对应起始面额库存充足时可正常运行:
- 测试用例找零金额:
[10, 4, 0.5, 0.05] - 预期逻辑:若收银机无10美元面额钞票,循环顺延检查5美元面额是否可用于找零,依次向下遍历更小面额
- 实际异常:循环直接跳过中间面额,跳转至1美元面额处理
- 前置约定:面额遍历起始索引已预先计算完成:
- 10美元遍历起始索引为
2(该索引前所有面额均大于10) - 4美元遍历起始索引为
4(对应收银机数组中1美元面额的索引) - 其余面额起始索引按相同规则推导
- 10美元遍历起始索引为
问题复现代码
let change = [ 10, 4, 0.5, 0.05 ] let denomin = [ 100, 20, 10, 5, 1, 0.25, 0.1, 0.05, 0.01 ] let register = [ 100, 60, 0, 55, 90, 4.25, 3.1, 2.05, 1.01 ] let idx = [ 2, 4, 5, 7 ] function test(ch, reg, idx) { for (let x of ch) { for (let i = idx[ch.indexOf(x)]; i < reg.length; i++) { if (reg[i] - x >= 0) { reg[i] -= x break; } else if (reg[i] - x < 0) { i++ } } } return reg = reg.map(a => Number(a.toFixed(2))) } console.log(test(change, register, idx))
根因分析
核心逻辑错误共2点,直接导致跳面额问题:
- 内层循环重复递增索引:
for循环的循环头已经定义每次迭代结束自动执行i++,当当前面额库存不足(进入reg[i] - x < 0分支)时,代码又手动执行了一次i++,相当于单次循环i总共加2,直接跳过相邻的下一个面额。
以处理第一个找零金额10为例:起始i=2(对应10美元面额,库存为0),进入else if分支手动i变为3,循环头迭代再执行i变为4,直接跳过i=3对应的5美元面额,落到i=4的1美元位置,和观测到的异常现象完全吻合。 - 隐含逻辑隐患:当前判断仅校验对应面额的总库存是否大于待找金额,没有结合
denomin面额数组计算当前面额最多可使用的张数/总金额,无法正确支持非整倍数面额凑整的场景;另外用ch.indexOf(x)获取索引起始值的写法,在找零数组存在重复金额时会永远返回第一个匹配项的索引,导致起始索引计算错误。
修复后代码
let change = [10, 4, 0.5, 0.05] let denomin = [100, 20, 10, 5, 1, 0.25, 0.1, 0.05, 0.01] let register = [100, 60, 0, 55, 90, 4.25, 3.1, 2.05, 1.01] let idx = [2, 4, 5, 7] function test(ch, reg, idx) { for (let x of ch) { let remain = x // 移除手动i++逻辑,避免跳索引 for (let i = idx[ch.indexOf(x)]; i < reg.length && remain > 0; i++) { const faceValue = denomin[i] // 计算当前面额最多可抵扣的金额 const deduct = Math.min(reg[i], Math.floor(remain / faceValue) * faceValue) if (deduct > 0) { reg[i] = Number((reg[i] - deduct).toFixed(2)) remain = Number((remain - deduct).toFixed(2)) } } } return reg.map(a => Number(a.toFixed(2))) } console.log(test(change, register, idx)) // 输出:[100, 60, 0, 45, 89, 3.75, 3.1, 2, 1.01]
修复逻辑说明:处理单笔找零金额时新增剩余待找金额变量,遍历到每个面额时计算该面额最多可抵扣的金额,扣减后更新剩余待找金额,直到剩余待找金额为0再跳出循环,同时移除手动递增i的错误逻辑,避免跳面额。
内容的提问来源于stack exchange,提问作者Qaqli
相关产品推荐
相关产品推荐

