揭秘大厂常考算法:微信红包算法详解

164 阅读4分钟

在互联网时代,微信红包成为了人们社交和支付中不可或缺的一部分。它不仅让人们在节日和特殊场合中感受到了欢乐,还在一夜之间让大量用户开通了微信支付。而在这背后,红包算法起到了至关重要的作用。今天,我们就来深入探讨一下这个大厂常考的红包算法。

一、微信红包的魅力与算法需求

微信红包的成功不仅仅在于其便捷的支付方式,更在于它独特的随机分配机制。想象一下,当一群人在群里抢红包时,每个人都怀着期待的心情,不知道自己能抢到多少金额,这种不确定性增加了抢红包的乐趣。而这就需要一个合理的算法来实现红包金额的随机分配,同时还要保证所有红包金额之和等于总金额。

1.1 产品思维与算法结合

从产品经理的角度来看,红包算法需要满足用户体验和业务需求。一方面,要让用户感受到随机性,每个红包的金额都不一样;另一方面,又要保证公平性,避免出现某个红包金额过大或过小的情况。这就需要将产品思维与算法相结合,快速开发出符合需求的 AI 应用。

二、红包算法的实现思路

2.1 核心需求

红包算法的核心需求是将总金额随机分配给指定数量的红包,并且所有红包金额之和要等于总金额。我们可以用两个参数来表示这个问题:total 表示总金额,num 表示红包的个数。最终输出一个包含每个红包金额的数组。

2.2 现有代码分析

/**
 * 
 * @returns {number}  total
 * @returns {number}  num
 * @returns {number[]}  
 * 
 */
function hongbao(total,num){
   const arr=[];
   let restAmount=total;//剩余金额
   let restNum=num;//剩余个数
   for(let i=0;i<num-1;i++){
       // Math 
       // 包装类
       let amount =Math.random(restAmount/restNum*2).toFixed(2);
       // console.log(amount);
       restAmount-=amount;
       restNum--;
       arr.push(amount);
   }
    //    - 公平性
    // 平均值
    // 随机性
     arr.push(restAmount.toFixed(2));
     return arr;
}
console.log(hongbao(100,20));

2.3 代码问题分析

然而,这段代码存在一些问题。首先,Math.random() 方法的使用有误,Math.random() 方法不接受参数,它会返回一个介于 0(包含)和 1(不包含)之间的随机小数。因此,Math.random(restAmount/restNum*2) 这样的调用是错误的。其次,toFixed(2) 方法返回的是一个字符串,而不是数字,在进行金额计算时会导致错误。

三、红包算法的优化实现

3.1 优化思路

为了实现一个正确的红包算法,我们可以采用以下思路:在每次分配红包时,随机生成一个金额,这个金额要保证在合理的范围内,即不能超过剩余金额的平均值的两倍,同时也要保证最后一个红包能分配到剩余的金额。

3.2 优化后的代码

/**
 * 
 * @param {number} total 总金额
 * @param {number} num 红包个数
 * @returns {number[]} 每个红包的金额数组
 */
function hongbao(total, num) {
    const arr = [];
    let restAmount = total; // 剩余金额
    let restNum = num; // 剩余个数

    for (let i = 0; i < num - 1; i++) {
        // 计算当前红包的最大可能金额
        const max = (restAmount / restNum) * 2;
        // 随机生成一个金额
        const amount = parseFloat((Math.random() * max).toFixed(2));
        arr.push(amount);
        restAmount -= amount;
        restNum--;
    }

    // 最后一个红包直接分配剩余金额
    arr.push(parseFloat(restAmount.toFixed(2)));

    return arr;
}

console.log(hongbao(100, 20));

3.3 代码解释

  • 首先,我们初始化一个空数组 arr 用于存储每个红包的金额,同时记录剩余金额 restAmount 和剩余个数 restNum
  • 然后,使用 for 循环进行 num - 1 次分配,每次分配时计算当前红包的最大可能金额 max,即剩余金额的平均值的两倍。
  • 接着,使用 Math.random() 方法生成一个随机小数,并乘以 max 得到一个随机金额,使用 toFixed(2) 方法保留两位小数,再使用 parseFloat() 方法将结果转换为数字。
  • 最后,将剩余的金额作为最后一个红包的金额添加到数组中。

四、总结

微信红包算法看似简单,但实际上需要考虑很多因素,如随机性、公平性和效率等。通过将产品思维与算法相结合,我们可以开发出符合用户需求的红包算法。在实现过程中,要注意代码的正确性和健壮性,避免出现逻辑错误。希望本文能帮助你深入理解微信红包算法,在面试或实际开发中能够游刃有余。