function checkCashRegister(price, cash, cid) {
var change;
var sumCid = 0; // Here is your change, ma'am. //找零(change),付款(cash),购买价格(price),收银机中零钱(cid)
change = cash - price; //计算零钱总额
for (var i = 0; i < cid.length; i++) {
sumCid += cid[i][1];
}
return sumCid;
sumCid = Number(sumCid.toFixed(2)); //保留两位小数 if (sumCid < change) {
return "Insufficient Funds"; //余额不足
} else if (sumCid === change) {
return "Closed";
} else {
// 1.零钱不够,返回余额不足
// 2.零钱足够,找回零钱
return overChange(change, cid, sumCid);
}
} function overChange(change, arr, sumCid) {
var array = [];
var len = arr.length; for (var i = len - 1; i >= 0; i--) {
if (arr[i][1] === 0) continue; if (arr[i][1] < change) {
array.push(arr[i]);
change -= arr[i][1];
change = Number(change.toFixed(2));
} else if (arr[i][1] > change) {
var x = arr[i][0]; // 取得零钱名称
var y = 0; switch(x) {
case "ONE HUNDRED":
y = Math.floor(change / 100) * 100;
break;
case "TWENTY":
y = Math.floor(change / 20) * 20;
break;
case "TEN":
y = Math.floor(change / 10) * 10;
break;
case "FIVE":
y = Math.floor(change / 5) * 5;
break;
case "ONE":
y = Math.floor(change / 1);
break;
case "QUARTER":
y = Math.floor(change / 0.25) * 0.25;
break;
case "DIME":
y = Math.floor(change / 0.10) * 0.10;
break;
case "NICKEL":
y = Math.floor(change / 0.05) * 0.05;
break;
case "PENNY":
y = Math.floor(change / 0.01) * 0.01;
break;
} if (y === 0 && sumCid - arr[i][1] < change) {
  return "Insufficient Funds";
} else if (y === 0) {
continue;
} else {
if (y < 1) {
y = y;
}
var array1 = [];
array1.push(arr[i][0]);
array1.push(y);
array.push(array1);
change -= y;
change = Number(change.toFixed(2));
}
}
} if (change === 0) {
return array;
} else {
return "Insufficient Funds";
} }

题目:

  设计一个收银程序 checkCashRegister() ,其把购买价格(price)作为第一个参数 , 付款金额 (cash)作为第二个参数, 和收银机中零钱 (cid) 作为第三个参数.

cid 是一个二维数组,存着当前可用的找零.

当收银机中的钱不够找零时返回字符串 "Insufficient Funds". 如果正好则返回字符串 "Closed".

否则, 返回应找回的零钱列表,且由大到小存在二维数组中.

分析:

  一个模拟找钱的程序。思路应该是这样的:

  首先,分析函数的参数,第一个参数是商品价格price,第二参数是支付现金金额cash,第三个是柜员机当前的零钱cid,是一个二维数组,它已经将所拥有的相同面值的钱币做了一个累加,比如面值为5元的就剩35元了这样。

  然后我们来分析函数的实现逻辑,结账时,会先扫描一下商品的价格,做一个累加,得到总的支付金额比如说78元,然后你给的钱是现金的话是不是要给50+20+5+1*3或者10*7+1*8等等等的组合。

  //找零(change),付款(cash),购买价格(price),收银机中零钱(cid)
change = cash - price;

但是你刚好没有零钱,最小100,你只能给100。那么此时基于交易等价交换的原则,柜员机得找零对吧,而且得找得回这么多零钱对吧,找不回就返回字符串"Insufficient Funds",表示零钱不足,交易基于等价交换的原则无法进行。那么你要先求找零的金额大小,然后与柜员机当前的零钱总额作比较。找零的金额为 cash - price,当前柜员机的零钱总额为各个面值大小的纸币的金额总额相加。数组是规律的,第一项是钱币面值,第二项是该面值的钱币总额。所以可以循环遍历叠加金额。

//计算零钱总额
for (var i = 0; i < cid.length; i++) {
sumCid += cid[i][1];
}

当可以找零的时候,你会拿钱,而且是一个面值的纸币一个面值的纸币的拿吧,不会找27元你找个27个一元钱吧。最简便的做法总是先给一张较大的但小于当前需要找零的零钱的纸币。这是使用循环变量递减的原因。

 for (var i = len - 1; i >= 0; i--) {

你没找零多少钱需要找得零钱总额在减小

change -= y;

还有一种情况就是,有可能柜员机零钱总额足够找零,但是找不开,比如说要找零3元,但你最小的纸币只剩下5元了,这时也是需要返回字符串"Insufficient Funds",表示零钱不足,交易基于等价交换的原则无法进行。

  if (y === 0 && sumCid - arr[i][1] < change) {
return "Insufficient Funds";
}
if (change === 0) {
return array;
} else {
return "Insufficient Funds";
}

change == 0 是判断能否成功找零的直接标准。

如果循环结束了,change != 0,说明现在的零钱找不开。否则返回需要找回的零钱。

方法参考文档

  

  Number.prototype.toFixed()

    toFixed() 方法使用定点表示法来格式化一个数。

    https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Number/toFixed

  

Exact Change FreeCodeCamp的更多相关文章

  1. Exact Change(背包HDU2753)

    Exact Change Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Total ...

  2. FCC高级编程篇之Exact Change

    Exact Change Design a cash register drawer function checkCashRegister() that accepts purchase price ...

  3. Exact Change(01背包)

    描述 Seller: That will be fourteen dollars. Buyer: Here's a twenty. Seller: Sorry, I don't have any ch ...

  4. Exact Change

    设计一个收银程序 checkCashRegister() ,其把购买价格(price)作为第一个参数 , 付款金额 (cash)作为第二个参数, 和收银机中零钱 (cid) 作为第三个参数. cid ...

  5. [Advanced Algorithm] - Exact Change

    题目 设计一个收银程序 checkCashRegister(),其把购买价格(price)作为第一个参数 , 付款金额 (cash)作为第二个参数, 和收银机中零钱 (cid) 作为第三个参数. ci ...

  6. UVA-11517 Exact Change(DP)

    题目大意:有n张钞票,面值可能不同.你要买一件东西,可能需要找零钱.问最少付多少钱,并求出最少的钞票张数. 题目分析:定义状态dp(i,w)表示前i张钞票凑成w元需要的最少钞票张数.则状态转移方程为d ...

  7. FCC(ES6写法) Exact Change

    设计一个收银程序 checkCashRegister() ,其把购买价格(price)作为第一个参数 , 付款金额 (cash)作为第二个参数, 和收银机中零钱 (cid) 作为第三个参数. cid  ...

  8. FreeCodeCamp 高级算法(个人向)

    freecodecamp 高级算法地址戳这里. freecodecamp的初级和中级算法,基本给个思路就能完成,而高级算法稍微麻烦了一点,所以我会把自己的解答思路写清楚,如果有错误或者更好的解法,欢迎 ...

  9. Codeforces Round #598 (Div. 3) A. Payment Without Change 水题

    A. Payment Without Change You have a coins of value n and b coins of value 1. You always pay in exac ...

随机推荐

  1. Linux系统学习之 三:新手必须掌握的Linux命令3

    内容预览 1.输入输出重定向 2.管道命令符 3.命令行的通配符 4.常用的转义符号 5.重要的环境变量 一.输入输出重定向 重定向技术的5种模式:1 标准覆盖输出重定向 错误覆盖输出重定向 错误追加 ...

  2. JUnit单元测试实践:测试工具类和方法(EmptyUtils)

    以前的时候(读大学时),我认为写单元测试太费事了.现在,我改变看法了. 工作中,为了提高Web开发的质量和效率,近期又为了保证自己的工具类等一系列可复用组件的质量,我煞费苦心地开始认真学习和撰写单元测 ...

  3. Ubuntu14.043下QT5.5的安装与一点问题

    请注明来自于 http://www.cnblogs.com/usegear/p/5100720.html 1.下载qt-opensource-linux-x86-5.5.0.run(去教育镜像网站下载 ...

  4. android的数据与访问(1)-我的app配置参数文件放在哪儿?

    系统提供数据处理方式: 1.SharedPreferences 2.文件存储 3.轻量级的数据.如SQLLite 1.简单存储 是android提供的起来年纪的数据存储方式:SharedPerence ...

  5. Redis Hash 的 HSET、HGET、HMSET、HMGET 性能测试

    [压测环境] 操作系统: Ubuntu 14.04 LTS Linux版本: 3.13.0-24-generic x86_64 GNU/Linux 处理器: 4核的 AMD Athlon(tm) II ...

  6. mdl 锁 SYSTEMTAP跟踪

    systemtap : 各种资源的使用限制由所生成的C代码中的宏来设置.这些值可在编译时由-D选项来重写.下面描述了部分挑选出来的宏: MAXNESTING 递归函数的最大调用层数,默认值是10. M ...

  7. C++设计模式之状态模式(二)

    2.智能空调的设计与实现 某软件公司将开发一套智能空调系统: 系统检測到温度处于20---30度之间,则切换到常温状态:温度处于30---45度,则切换到制冷状态: 温度小于20度,则切换到制热状态. ...

  8. HDOJ GCD 2588【欧拉函数】

    GCD Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submis ...

  9. luogu2261 [CQOI2007] 余数之和

    题目大意 求 \[\sum_{i=1}^{n}(k\mod i)\] \(n,k\leq 10^9\). 题解 先只考虑\(n\leq k\)的情况. \[\sum_{i=1}^{n}(k\mod i ...

  10. androidstudio集成ijkplayer教程

      介绍 ijkplayer是一款非常火的开源视频播放器,android和IOS通用.关于怎么编译怎么导入android Studio中自己的项目,其中坑很多,本篇记录下自己的操作记录.ijkplay ...