我在freecodecamp中进行JS算法和数据结构项目,而我陷入了最后一个问题“收银机”。我已经做了一些编码,而我的代码没有通过所有测试。
问题的链接:https : //www.freecodecamp.org/learn/javascript-algorithms-and-data-structures/javascript-algorithms-and-data-structures-projects/cash-register
我的代码未通过3和5数字测试。在数字3中,输出几乎相同,但是最后一部分[“ PENNY”,0.03]与输出不匹配。在数字5中,totalCid
和cashback
变量相等,但不会返回“ CLOSED”。如果相等,则应返回状态“ CLOSED”。
function checkCashRegister(price, cash, cid) {
var cashback = (cash - price)
var returnMoney = {
status: "",
change: []
}
var totalCid = cid.map(v => {
return v[1]
})
.reduce((a, b) => {
return a + b
})
.toFixed(2)
console.log(cashback)
console.log(totalCid)
if (totalCid === cashback) {
returnMoney.status = "CLOSED"
returnMoney.change = cid
return returnMoney
} else if (totalCid < cashback) {
returnMoney.status = "INSUFFICIENT_FUND"
returnMoney.change = []
return returnMoney
} else {
var denomValue = [{
bill: "ONE HUNDRED",
val: 100
},
{
bill: "TWENTY",
val: 20
},
{
bill: "TEN",
val: 10
},
{
bill: "FIVE",
val: 5
},
{
bill: "ONE",
val: 1
},
{
bill: "QUARTER",
val: 0.25
},
{
bill: "DIME",
val: 0.10
},
{
bill: "NICKEL",
val: 0.05
},
{
bill: "PENNY",
val: 0.01
}
]
var newCidArray = [];
var currVal = 0;
for (let i = 0; i < denomValue.length; i++) {
while (cashback >= denomValue[i].val && currVal < cid[8 - i][1]) {
cashback -= denomValue[i].val.toFixed(2);
currVal += denomValue[i].val;
}
if (currVal > 0) {
newCidArray.push([denomValue[i].bill, currVal]);
}
currVal = 0; // reset current value (currVal) to zero after the loop has completed
}
returnMoney.status = "OPEN"
returnMoney.change = newCidArray
return returnMoney
}
}
console.log(checkCashRegister(19.5, 20, [
["PENNY", 0.5],
["NICKEL", 0],
["DIME", 0],
["QUARTER", 0],
["ONE", 0],
["FIVE", 0],
["TEN", 0],
["TWENTY", 0],
["ONE HUNDRED", 0]
]))
您的代码中总共有3个问题。
@trincot指出了第一个:toFixed()
返回一个字符串,您不能将其与===
数字进行比较。
第二个原因是,即使抽屉中的现金多于预期的零钱,您也可能会遇到INSUFFICIENT_FUNDS
这种情况,因为您无法拆分所拥有的钞票(纸币,英式英语)和硬币。这意味着在算法结束时,您必须检查更改是否汇总。
第三个也是主要的一个来自浮点数运算。如果单击“在代码下运行代码段”,您会看到更改将是0.49000000000000027
几美分。
摆脱浮点沼泽的唯一安全方法是将所有内容都转换为整数。因此,除了解决前两个问题外,我所做的就是在脚本中将美元转换为几美分。尽管如此,我还是尽量不要改变您的脚本。
function checkCashRegister(price, cash, cid) {
// P stands for pennies
var cidP = cid.map(v => [v[0], Math.round(v[1] * 100)])
var priceP = Math.round(price * 100)
var cashP = Math.round(cash * 100)
var cashbackP = (cashP - priceP)
var returnMoney = {
status: "",
change: []
}
var totalCidP = cidP.map(v => {
return v[1]
})
.reduce((a, b) => {
return a + b
})
if (totalCidP === cashbackP) {
returnMoney.status = "CLOSED"
returnMoney.change = cid
return returnMoney
} else if (totalCidP < cashbackP) {
returnMoney.status = "INSUFFICIENT_FUNDS"
returnMoney.change = []
return returnMoney
} else {
var denomValueP = [
{bill: "ONE HUNDRED", val: 10000},
{bill: "TWENTY", val: 2000},
{bill: "TEN", val: 1000},
{bill: "FIVE", val: 500},
{bill: "ONE", val: 100},
{bill: "QUARTER", val: 25},
{bill: "DIME", val: 10},
{bill: "NICKEL", val: 5},
{bill: "PENNY", val: 1}
]
var changeArray = [];
for (let i = 0; i < denomValueP.length; i++) {
var currValP = 0;
while (cashbackP >= denomValueP[i].val && currValP < cidP[8 - i][1]) {
cashbackP -= denomValueP[i].val;
currValP += denomValueP[i].val;
}
if (currValP > 0) {
changeArray.push([denomValueP[i].bill, currValP / 100]);
}
}
if (cashbackP === 0) {
returnMoney.status = "OPEN"
returnMoney.change = changeArray
} else {
returnMoney.status = "INSUFFICIENT_FUNDS"
returnMoney.change = []
}
return returnMoney
}
}
至于为什么Math.round()
需要这些,请尝试以下操作:
4567.89 * 100 === 456789 // => false
编辑
您要求对代码中的最后一个if-else进行澄清。freecodecamp的第四段说:
返回
{status: "INSUFFICIENT_FUNDS", change: []}
如果现金抽屉内小于应有的改变,或者如果您不能返回的零钱。
如果您已达到算法的结尾cashbackP
,并且您为添加到零钱中的每张钞票或硬币而一直在减少的算法就没有变为零,这意味着零钱尚未完成,并且您处于我强调的情况。
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句