如何用代码寻找最优的用券解决方案?这是最近我一朋友找我咨询的业务问题,问我有没有好方法,刚开始看起来确实挺让人头疼,我们用文字列出两种方案,不难发现第一种是无法顺利兑换所有奖品的,但只并不意味着你的券不够额度,而是你的使用姿势不对,如果将使用姿势改成方案二,皆可以满足所有奖品的兑换。
那如何用代码去寻找最优解,这是他遇到的难题。我的想法是:首先将奖品不适用用户拥有优惠券的过滤掉,例如戴洛伦的使用范围H1过滤掉,那就是戴洛伦适用:H1,星巴克适用:H2、H3,小甘菊适用H2
接着根据适用的券数量从少到多排序:顺序依次是:戴洛伦->小甘菊->星巴克
接着就可以按着顺序使用券,通过代码表达出来如下
class Reword {
constructor(name, amount, range) {
this.name = name;
this.amount = amount;
this.range = range;
}
}
class Coupon {
constructor(name, amount, range) {
this.name = name;
this.amount = amount;
this.range = range;
}
}
var DLL_Reword = new Reword("戴洛伦", 50, ["H2", "H3"])
var XBK_Reword = new Reword("星巴克代金券100元", 100, ["H2", "H3"])
var XGJ_Reword = new Reword("小甘菊礼盒", 200, ["H2"])
var H2Coupon = new Coupon("H2券", 200, "H2")
var H3Coupon = new Coupon("H3券", 200, "H3")
var allRewords = [DLL_Reword, XBK_Reword, XGJ_Reword]
var myCoupons = [H2Coupon, H3Coupon]
var needPay = 0
let couponArr = []
myCoupons.forEach(x => {
couponArr.push(x.range)
})
//将无优惠券的使用范围去除
for (let i = allRewords.length - 1; i >= 0; i--) {
for (let j = allRewords[i].range.length - 1; j >= 0; j--) {
if (couponArr.indexOf(allRewords[i].range[j]) == -1) {
allRewords[i].range.splice(j, 1)
}
}
}
//通过使用范围的大小来排序
allRewords = allRewords.sort((a, b) => a.range.length - b.range.length)
console.log(allRewords);
/**
* 计算优惠券剩余金额
* 计算超出部分的金额
*/
for (let i = 0; i < allRewords.length; i++) {
for (let j = 0; j < allRewords[i].range.length; j++) {
switch (allRewords[i].range[j]) {
case "H2":
if (H2Coupon.amount >= allRewords[i].amount) {
H2Coupon.amount -= allRewords[i].amount
} else {
allRewords[i].amount -= H2Coupon.amount
H2Coupon.amount = 0
}
break;
case "H3":
if (H3Coupon.amount >= allRewords[i].amount) {
H3Coupon.amount -= allRewords[i].amount
} else {
allRewords[i].amount -= H3Coupon.amount
needPay += H3Coupon.amount
H3Coupon.amount = 0
}
break;
}
}
}
console.log(H2Coupon);
console.log(H3Coupon);
console.log(needPay);