FCC高级编程篇之Exact Change

Exact Change

Design a cash register drawer function checkCashRegister() that accepts purchase price as the first argument (price), payment as the second argument (cash), and cash-in-drawer (cid) as the third argument.
cid is a 2D array listing available currency.
Return the string "Insufficient Funds" if cash-in-drawer is less than the change due. Return the string "Closed" if cash-in-drawer is equal to the change due.
Otherwise, return change in coin and bills, sorted in highest to lowest order.

考察浮点数运算

本题中小于1美元的部分如果直接运算会产生一定的误差。因此所有数都乘以100,最后输出时再除100。

function checkCashRegister(price, cash, cid) {
  const deno = {
    'PENNY': 1,
    'NICKEL': 5,
    'DIME': 10,
    'QUARTER': 25,
    'ONE': 100,
    'FIVE': 500,
    'TEN': 1000,
    'TWENTY': 2000,
    'ONE HUNDRED': 10000
  };
  let result = [];

  return result;
}

checkCashRegister()方法传入了三个参数。

  • 第一个参数是价格
  • 第二个参数是收到的金额
  • 第三个参数cid是一个数组,表示可用于找零的钱

首先把传入的cid的值都乘以100。

let cidObj = {};

for (let i in cid) {
  cidObj[cid[i][0]] = cid[i][1] * 100;
}

找零的钱也要乘以100。

let change = (cash - price) * 100;

收银台需要有小于或等于要找的零钱的钱,为此需要获得各种面额的名称以及钱数。判断收银台的钱是否有比要找的钱小的面值,以及此面额是否有钱。

let keys = Object.keys(deno);
let i = keys.length - 1;

while (i >= 0) {
  while (deno[keys[i]] <= change && !!cidObj[keys[i]]) {
    change -= deno[keys[i]];
    cidObj[keys[i]] -= deno[keys[i]];
  }
  i--;
}

如果经过上述循环后,change不为零,则说明找不开。

if (!!change) {
  return "Insufficient Funds";
}

如果找得开,则判断收银台里是否还有钱。

for (let i in cidObj) {
  if (!!cidObj[i]) {
    break;
  } else if (i === keys[keys.length - 1]) {
    return "Closed";
  }
}

如果还有钱,则计算收银台在找完钱后还剩多少钱。这里需要有收银台原来的钱数,故在先前cid传入后多拷贝一个。引用类型需进行深拷贝。

let cidObj = {};
let objCopy = {};

for (let i in cid) {
  cidObj[cid[i][0]] = cid[i][1] * 100;
  objCopy[cid[i][0]] = cid[i][1] * 100;
}

然后判断各种面额的钱数是否有变化。

for (let i in objCopy) {
  if (objCopy[i] !== cidObj[i]) {
    result.unshift([i, (objCopy[i] - cidObj[i]) / 100]);
  }
}

最后输出result即可。完整代码如下。

function checkCashRegister(price, cash, cid) {
  const deno = {
    'PENNY': 1,
    'NICKEL': 5,
    'DIME': 10,
    'QUARTER': 25,
    'ONE': 100,
    'FIVE': 500,
    'TEN': 1000,
    'TWENTY': 2000,
    'ONE HUNDRED': 10000
  };
  let cidObj = {};
  let objCopy = {};
  let keys = Object.keys(deno);
  let i = keys.length - 1;
  let change = (cash - price) * 100;
  let result = [];

  for (let i in cid) {
    cidObj[cid[i][0]] = cid[i][1] * 100;
    objCopy[cid[i][0]] = cid[i][1] * 100;
  }

  while (i >= 0) {
    while (deno[keys[i]] <= change && !!cidObj[keys[i]]) {
      change -= deno[keys[i]];
      cidObj[keys[i]] -= deno[keys[i]];
    }
    i--;
  }

  if (!!change) {
    return "Insufficient Funds";
  }

  for (let i in cidObj) {
    if (!!cidObj[i]) {
      break;
    } else if (i === keys[keys.length - 1]) {
      return "Closed";
    }
  }

  for (let i in objCopy) {
    if (objCopy[i] !== cidObj[i]) {
      result.unshift([i, (objCopy[i] - cidObj[i]) / 100]);
    }
  }

  return result;
}

运行结果如下图所示。

Exact Change测试结果图

posted @ 2017-11-06 23:32  月宫  阅读(197)  评论(0编辑  收藏  举报