一些前提解释
我要讨论的红包是:微信拼手气红包。
拼手机红包的一些的限制条件如下: – 每个红包最小为0.01元,所以每个红包至少要分到0.01元。
输入数据:
- 红包总金额 amount
- 红包个数 count 如果 amount / count < 0.01 元,报错:单个红包金额不可低于0.01元,请重新填写金额。
输出数据:
一个数组:数组中包括 count 个红包金额(每个金额都大于等于0.01元,所有红包的金额加起来等于总金额 amount)
一个重要的问题
首先我们先确定一个重要的问题:每个红包的金额是先生成好还是在边抽边生成?
为了解决高并发过程中锁的问题,明显先生成每个红包的金额更简单更效率。
我的思路
我首先想到的思路:
假设 100 块钱,要发10个拼手气红包。
从1—100 随机10个数字。[20, 61, 97, 39 ,32, 48, 10, 20, 48, 78]
第一步:获取随机值
1 2 3 4 5 6 7 |
|
第二步:计算红包金额:
1 2 3 |
|
好像已经差不多答案了。。
但是有几个问题需要考虑:
- 精度为0.01元,金额不能出现 4.415011
- 如果算出来的红包金额小于0.01元,怎么办?
解决办法:
- 所有的红包金额需要 floor (舍掉多余的小数位) : 比如 a1 的金额 从 4.415011 –> 4.41,最后一个红包 = 红包总金额 – 已经 floor 的红包的和
- 不管是否小于0.01,先把每个红包的金额计算出来。发现自己 = 0 ,从下一个红包中拿0.01,发现自己 = – 0.01 ,从下一个红包中拿 0.02, 直到所有的红包都 > 0
可能还有的问题:
- 如何避免出现100块的红包分给11个人,分成了99块+ 0.1 * 10个情况,不知道现在的微信红包是否可能出现这个问题,这个问题李业(我同事)的做法是使用上面的结果做一个正态分布的换算,非常好的想法。
测试:
本文链接: http://lijinma.com/blog/2015/12/19/how-to-design-the-wechat-lucky-money/