基于JavaScript的彩票中奖者抽取逻辑实现疑问
如何根据用户持有的彩票数量抽取中奖者
嘿,这个需求其实很典型,核心逻辑就是让用户的中奖概率和他持有的票数成正比——票数越多,对应的“中奖区间”就越大,被抽中的几率也就越高。结合你现有的代码,我给你整理了一套完整的实现方案:
核心思路
- 给每个用户分配一个连续的数字区间:比如第一个用户有291张票,对应的区间就是
0 ~ 290;第二个用户302张,区间是291 ~ 592(291+302-1);第三个用户72张,区间是593 ~ 664。 - 生成一个0到「总票数-1」的随机整数,看这个数落在哪个用户的区间里,这个用户就是中奖者。
完整代码实现
var lotteryTickets = [ { name: 'John Smith', tickets: 291 }, { name: 'Bob the Builder', tickets: 302 }, { name: 'Elizabeth', tickets: 72 } ]; var lotteryTotal = 0; lotteryTickets.forEach(function(data){ lotteryTotal += data.tickets; }); $('.tickets').text(lotteryTotal); // 定义抽取中奖者的函数 function drawWinner() { // 生成0到lotteryTotal-1之间的随机整数 const randomNum = Math.floor(Math.random() * lotteryTotal); let currentTicketSum = 0; // 遍历用户数组,累加票数判断随机数所属区间 for (const user of lotteryTickets) { currentTicketSum += user.tickets; // 当累计票数超过随机数时,当前用户就是中奖者 if (randomNum < currentTicketSum) { return user; } } // 极端情况(总票数为0)下的返回值 return null; } // 调用函数获取中奖者 const winner = drawWinner(); console.log(`恭喜 ${winner.name} 中奖!他持有 ${winner.tickets} 张彩票`);
逻辑说明
- 这个方法完全符合概率公平性:比如Bob有302张票,总票数是665,他的中奖概率就是
302/665,和他的票数占比完全一致。 - 代码里的循环遍历效率很高,哪怕用户数量多一点也能快速定位中奖者;如果是超大规模的用户列表,还可以预先计算好每个用户的区间上限,用二分查找来进一步提升效率。
内容的提问来源于stack exchange,提问作者OrpheuZ




