在微信群里面发红包,每个人能拿到多少钱呢?这个数额是怎样算出来的呢?这个算法告诉你!
讲解例子:1元分配给20个人
在微信抢过红包的细心朋友都会发现,每个红包的金额即使再小,下限也是1分钱,同样不可能是0元或者更少。所以红包分配算法做初始化的时候,必须先保证每个红包都不能出现0元或负数。我们可以先给每个红包分配一分钱,如例子所示,系统就会先拿出2角,分给这些用户每人1分钱,剩下的8角再进行后续分配。这样,就保证了每个红包至少1分钱的入账。
于是,我们就需要注意一个问题,既然每个人至少一分钱,所以n人的红包总数额不能低于n分钱。系统会在这里先做判断,若不能保证每个红包至少一分钱,如4分钱分给5个人,系统就会报错。
上一步我们介绍了,先给每个人分配1分钱,接下来再分配剩下的8角(allocateSum)。8角等于80分钱,因此系统先随机生成20个0到80的随机数(randNum数组),这一趟循环还需要对随机数求和(randSum)。
然后,每个随机数占随机数和的比例,跟每个红包放的钱占总分配钱(即本例的8角)的比例是一样的。所以,每个红包分配到的金额数,可以先用数组中与自己对应的随机数(例如你是第8个人,那就是randNum【7】)除以随机数和(randSum),得出比值,再乘以可分配数额(allocateSum)得出。因为金额的最小单位是分,所以需要做四舍五入。加上最初固定的1分钱,那所有红包的数额都计算出来了。
(公式)
可是,真的有这么简单吗?
上述算法提到有一个重要的操作,四舍五入。对数学有了解的朋友都知道,直接做四舍五入不能完全保证分配的金额总数刚好就是可分配金额数。原因很简单,每个数做四舍五入,都带有一定的随机性,可能增加也可能舍去,但增加与舍去不能保证完全相等。但金钱却非常注意严谨,你总不可能让红包的总数跟每个人领到的数目之和不一样的尴尬情况出现吧!
当然,也有很简单的解决办法,就是对于前面(n-1)个红包采用上述随机数比值的分配方式,最后一个红包就不用这种方式了,改为拿可分配金额数减去之前(n-1)个红包已经分配的金额数。也就是说,前面(n-1)个分配完,剩下的都会留给最后一个红包。这样,就能确保每个红包分配到的总数跟可分配总数一样了。