思路见注释:
设计一个收银程序 checkCashRegister()
,其把购买价格(price
)作为第一个参数 , 付款金额 (cash
)作为第二个参数, 和收银机中零钱 (cid
) 作为第三个参数.
cid
是一个二维数组,存着当前可用的找零.
当收银机中的钱不够找零时返回字符串 "Insufficient Funds"
. 如果正好则返回字符串 "Closed"
.
function checkCashRegister(price, cash, cid) {
//应找回的金额
var change;
//匹配对应币值
var payarr=[
0.01,
0.05,
0.1,
0.25,
1.0,
5.0,
10.0,
20.0,
100.0
];
//初始化
var payobj={
"PENNY":0,
"NICKEL":0,
"DIME":0,
"QUARTER":0,
"ONE":0,
"FIVE":0,
"TEN":0,
"TWENTY":0,
"ONE HUNDRED":0
};
//获取币种种类
var i=payarr.length-1;
//初始化
change=cash-price;
var out=[];
var flag;
var sum=0;
//获取数组中指定列所有数和
function money(arr,id){
var i=0;
arr.forEach(function(val){
i+=val[id];
});
return i;
}
//支付函数
function checke(change,i){
// console.log(change,i,payarr[i]);
if(change>=payarr[i]&&cid[i][1]>0&&i>=0){
change=(change-payarr[i]).toFixed(2);//每次计算后保留两位小数位,防止丢失
//支付后cid的余额应该减少
cid[i][1]-=payarr[i];
payobj[cid[i][0]]+=payarr[i];
checke(change,i);//减完之后再次判断是否能用当前币值的货币退钱
}else if(change<payarr[i]&&i>0||cid[i][1]==0&&i>0){/*当前币种大于应找余额时切换至更低的币种*/
checke(change,i-1);//切换至更低币值
}
else return;//无法切换时退出
}
var l=change-money(cid,1);//应找钱与当前所剩钱的差值
checke(change,i);
console.log(payobj);
Object.keys(payobj).forEach(function(key){
if(payobj[key]>0){var arr1=[key,payobj[key]];
out.unshift(arr1);//队列压入数组
sum+=payobj[key];//保留支出金额数目
}
});
if(l==0)return "Closed";//如果支出的钱等于cid剩余钱就返回“Closed”
else if(l>0||sum<change)return "Insufficient Funds";//如果cid钱不够,返回“Insufficient //Funds”
else return out;//其他情况输出找出的币值及其金额
}
// Example cash-in-drawer array:
// [["PENNY", 1.01],
// ["NICKEL", 2.05],
// ["DIME", 3.10],
// ["QUARTER", 4.25],
// ["ONE", 90.00],
// ["FIVE", 55.00],
// ["TEN", 20.00],
// ["TWENTY", 60.00],
// ["ONE HUNDRED", 100.00]]
checkCashRegister(19.50, 20.00, [["PENNY", 1.01], ["NICKEL", 2.05], ["DIME", 3.10], ["QUARTER", 4.25], ["ONE", 90.00], ["FIVE", 55.00], ["TEN", 20.00], ["TWENTY", 60.00], ["ONE HUNDRED", 100.00]]);
.toFixed(d)保留D位小数,浮点数计算时会丢失精度