问题
面试官:抢红包,定义一个类,传递红包大小和人数,定义一个roll方法,每人最少分0.01,当roll调用次数大于人数的时候报错,roll返回每个人红包大小
解决步骤
-
constructor构造函数:- 接受
money和count作为参数,表示红包的总金额和总人数。 - 在构造函数中,首先进行检查,确保总金额足够分配给所有人。如果总金额不足以保证每人至少分到 0.01 元,就会抛出错误。
- 将传入的
money、count和一个初始的rolls(已抢红包的次数)保存为类的成员变量。
- 接受
-
roll方法:- 当调用
roll方法时,首先检查是否已经抢完了所有的红包。如果已经抢完,就会抛出错误。 - 增加
rolls计数表示已抢红包的人数。 - 当所有人都已经抢到红包的情况下,将剩余的金额返回给最后一个人。
- 计算每人分到的最小金额
minAmount,然后根据剩余的总金额和剩余人数计算每人分到的最大金额maxAmount。 - 生成一个随机比例因子,将其乘以
maxAmount - minAmount,再加上minAmount,得到每人分到的随机金额。 - 将分配的金额从总金额中减去,以更新剩余总金额。
- 使用
toFixed(2)将随机金额保留两位小数,以确保输出的金额格式正确。
- 当调用
-
创建一个
RedPacket实例,并进行 5 次循环,每次抢红包,输出每个人的红包大小。
// 抢红包,定义一个类,传递红包大小和人数,定义一个roll方法,每人最少分0.01,当roll调用次数大于人数的时候报错,roll返回每个人红包大小
class RedPacket {
constructor(money, count) {
if (money < count * 0.01) {
throw new Error("总金额并不足够所有人使用");
}
this.money = money; // 总金额
this.count = count; // 总人数
this.rolls = 0;
}
roll() {
if (this.rolls >= this.count) {
throw new Error("来晚了,红包已经被抢完了!");
}
this.rolls++;
// 在所有人都已经抢到红包的情况下,将剩余的金额返回给最后一个人。
if (this.rolls === this.count) {
return this.money.toFixed(2);
}
// 每个人分到的最小金额,根据题目要求为 0.01
const minAmount = 0.01;
// 是每个人分到的最大金额,它根据剩余的总金额以及剩余的人数来计算。
const maxAmount =
(this.money - (this.count - this.rolls) * minAmount) /
(this.count - this.rolls);
// 使用 Math.random() 生成一个随机的比例因子,它的范围在 0 到 1 之间。
// 将这个随机的比例因子乘以最大金额和最小金额的差值,然后加上最小金额,得到一个在最小金额和最大金额之间的随机金额。
const amount = Math.random() * (maxAmount - minAmount) + minAmount;
// 将分配的金额从总金额中减去,以更新剩余总金额。
this.money -= amount;
// 使用 toFixed(2) 将金额保留两位小数,以确保输出的金额格式正确。
return amount.toFixed(2);
}
}
// 创建一个红包,总金额为 10,总人数为 5
const redPacket = new RedPacket(10, 5); // 创建一个红包,总金额为 10,总人数为 5
// 循环5次,每次抢红包,输出每个人的红包大小
for (let i = 0; i < 5; i++) {
console.log(`Person ${i + 1} gets ${redPacket.roll()} yuan`);
}