收银机问题(不是最优解,但是是可行的)
编写一个用于收银机的函数checkCashRegister()
,传入售价为第一个参数(price
)、支付金额为第二个参数(cash
)、收银机內的金额为第三个参数(cid
)。
cid
是包含货币面值的二维数组。
函数checkCashRegister()
必须返回含有status
键值和change
键值的对象。
如果收银机內的金额少于应找回的零钱数,或者你无法返回确切的数目时,返回{status: "INSUFFICIENT_FUNDS", change: []}
。
如果收银机內的金额等于应找回的零钱数,返回{status: "CLOSED", change: [...]}
,其中change
键值是收银机內的金额。
否则,返回{status: "OPEN", change: [...]}
,其中change
键值是应找回的零钱数,并且它的面值由高到低排序。
货币单位 | 面值 |
---|---|
Penny | $0.01 (PENNY) |
Nickel | $0.05 (NICKEL) |
Dime | $0.1 (DIME) |
Quarter | $0.25 (QUARTER) |
Dollar | $1 (ONE) |
Five Dollars | $5 (FIVE) |
Ten Dollars | $10 (TEN) |
Twenty Dollars | $20 (TWENTY) |
One-hundred Dollars | $100 (ONE HUNDRED) |
function checkCashRegister(price, cash, cid) {
var change;
// 要找的钱
const map = {
PENNY: 0.01,
NICKEL: 0.05,
DIME: 0.1,
QUARTER: 0.25,
FIVE: 5,
TEN: 10,
TWENTY: 20,
'ONE HUNDRED': 100,
ONE:1
};
const mon = cash * 100 - price * 100;
const cacheCid = [].concat(cid) // 缓存一份原始数据
cid.sort((a, b) => {
return map[b[0]] - map[a[0]]; // 从大到小排列
});
let all = 0; // 收银机总钱数
let temp = []; //当前查到的数组
let tempNum = 0; // 当前查到的钱数
cid.forEach(a => {
all += a[1] * 100; // 计算收银机总钱数
});
if (all < mon) {
// 收银机总钱数小于要找的钱数
change = { status: 'INSUFFICIENT_FUNDS', change: [] };
} else if (all === mon) {
//收银机总钱数等于要找的钱数 这里注意返回的原始数组,不是重新排列后的数组
change = { status: 'CLOSED', change: cacheCid };
} else {
// 遍历收银机的钱数
for (let i = 0; i < cid.length; i++) {
let e = cid[i]; // 当前遍历项
let a = Math.floor((mon - tempNum) / (map[e[0]] * 100)); // 剩余要找的钱数 在当前遍历项里最多可以拿几个
if (a > 0) {
// 可以在当前项里拿a个
if (map[e[0]] * a > e[1]) {
//要拿的个数超出当前项的总数,只能拿当前项的总数
temp.push(e);
tempNum += e[1] * 100;
} else {
// 直接拿取应该拿的个数
temp.push([e[0], map[e[0]] * a]);
tempNum += map[e[0]] * a * 100;
}
if (tempNum === mon) {
// 如果当前拿的总数目已经和要找的钱数相同,直接跳出循环
break;
}
}
}
if (tempNum === mon) {
// 如果找的钱正好满足条件
change = { status: 'OPEN', change: temp };
} else {
// 找完了发现不满足条件
change = { status: 'INSUFFICIENT_FUNDS', change: [] };
}
}
// Here is your change, ma'am.
return change;
}
// Example cash-in-drawer array:
// [["PENNY", 1.01],
// ["NICKEL", 2.05],
// ["DIME", 3.1],
// ["QUARTER", 4.25],
// ["ONE", 90],
// ["FIVE", 55],
// ["TEN", 20],
// ["TWENTY", 60],
// ["ONE HUNDRED", 100]]
checkCashRegister(19.5, 20, [["PENNY", 1.01], ["NICKEL", 2.05], ["DIME", 3.1], ["QUARTER", 4.25], ["ONE", 90], ["FIVE", 55], ["TEN", 20], ["TWENTY", 60], ["ONE HUNDRED", 100]]);