You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

JS实现收银找零算法:从面额数组扣减使找零总额恰好归零

收银机找零功能逻辑修复方案

现有代码核心问题

  • 面额遍历逻辑错误:内置面额数组从最小面额0.01升序排列,找零未遵循优先使用大面额的现实逻辑,通过unshift插入符合条件面额的处理顺序混乱,且完全没有做库存金额校验
  • 浮点数运算精度风险:直接对小数做加减计算,JS本身的浮点数精度缺陷会导致剩余找零额计算出现偏差,比如0.1+0.2≠0.3的经典问题
  • 输出格式不符合要求:当前返回的myArr2存储的是每次扣减后的剩余找零金额,不是实际付出的面额值,和预期输出结构完全不符
  • 扣减逻辑缺失:没有循环判断当前面额最多可以用多少张,只要面额小于初始找零额就直接加入数组,完全不考虑扣减后剩余金额是否为负、库存是否足够

实现逻辑参考

  • 优先把所有金额统一乘以100转为整数(按分计算),从根源规避浮点数运算精度问题
  • 面额配置表按面额值从大到小倒序排列,遍历的时候优先匹配大面额,符合日常收银找零逻辑
  • 遍历每个面额时,同时校验两个条件:当前剩余待找零金额大于等于单张面额值、收银机内该面额的剩余库存金额大于0
  • 满足条件时循环扣减:每次扣减1张当前面额,同步更新剩余待找零额、该面额剩余库存、累计当前面额的使用总金额,直到不满足上述两个条件时,再切换到下一个更小的面额
  • 所有面额遍历完成后,判断剩余待找零额是否为0,为0则返回收集到的找零面额数组,不为0说明现有库存无法凑出刚好的找零金额

修复后可运行代码

function checkCashRegister(price, cash, cid) {
  // 待找零金额转成整数(单位:分)
  let changeRemain = Math.round((cash - price) * 100);
  // 面额配置从大到小排序,单位统一转成分
  const denominationList = [
    ["ONE HUNDRED", 10000],
    ["TWENTY", 2000],
    ["TEN", 1000],
    ["FIVE", 500],
    ["ONE", 100],
    ["QUARTER", 25],
    ["DIME", 10],
    ["NICKEL", 5],
    ["PENNY", 1]
  ];
  // 收银机库存转成整数分存储
  const stockMap = {};
  cid.forEach(([denominationName, amount]) => {
    stockMap[denominationName] = Math.round(amount * 100);
  });
  const changeResult = [];

  for (const [name, unitValue] of denominationList) {
    let currentDenominationTotal = 0;
    // 尽可能多用当前面额找零
    while (changeRemain >= unitValue && stockMap[name] > 0) {
      changeRemain -= unitValue;
      stockMap[name] -= unitValue;
      currentDenominationTotal += unitValue;
    }
    // 当前面额有使用的话,转回元单位加入结果数组
    if (currentDenominationTotal > 0) {
      changeResult.push(currentDenominationTotal / 100);
    }
  }

  // 刚好凑齐找零返回结果,否则返回库存不足提示
  return changeRemain === 0 ? changeResult : "收银机库存不足,无法完成找零";
}

// 测试用例1:消费70元支付100元,找零30元,输出 [20, 10]
console.log(checkCashRegister(70, 100, [["PENNY", 1.01], ["NICKEL", 2.05], ["DIME", 3.1], ["QUARTER", 4.25], ["ONE", 90], ["FIVE", 55], ["TEN", 20], ["TWENTY", 60], ["ONE HUNDRED", 100]]));
// 测试用例2:找零5.5元,输出 [5, 0.5]
console.log(checkCashRegister(94.5, 100, [["PENNY", 1.01], ["NICKEL", 2.05], ["DIME", 3.1], ["QUARTER", 4.25], ["ONE", 90], ["FIVE", 55], ["TEN", 20], ["TWENTY", 60], ["ONE HUNDRED", 100]]));

内容的提问来源于stack exchange,提问作者CRISVOSS

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.26 21:27:25