javascript发红包算法,粗糙版?

提问 1 203
来自:北京市-电信
二倍均值法:
假设总金额是M元,N个人,每次抢的金额=(0, (M/N) *2),比如,还是之前说的条件,金额100,人数10,

第一个人抢的金额是 (0,20),抢到的数值,根据正态分布,应该是10左右,远低于10的概率很小,同样远大于10的概率和很小,这里假设第一个人抢到的数值是10;

第二个人抢的金额是(0,90/9 *2)=(0,20),同第一个人,第二个人红包金额也应该是10附近;

剩下的人,以此类推。

查阅了“微信红包的架构设计”,里面就是使用的这个方法。但是,这个算法,也不是完美的,假如第一个人抢到15,第二个人的范围是(0,18.89),假如第二个人又抢到很高,那对后面的人是不利的

另外,还看到了一种叫“线性切割法”的算法,这个算法的思想是:把总金额数值,想象成一条绳子,对绳子切割N-1刀(N就是人的数量),每个人抢到的红包金额就是切割的绳子的占比,但是,这方法也不能避免“无限循环小数”问题;并且,对每个人抢到的金额尽量平均,该如何保证呢?需要考虑的点很多,时间复杂度、空间复杂度都比较高
     // 生成随机数范围值,保留两位小数
function random(m, n) {
let r = Math.random()*(m-n)+n
let res = (r*100).toString().split('.')[0]
res = Number(res)/100
return res
}

function randAlloc(totals, n) {
let resValue = 0
let result = []
let total = totals
let length = n

for(let i=0; i<length-1; i++) {
let n = random((total-resValue)/(length-i)*2, 0.01)
resValue= (resValue*100+n*100)/100
result.push(n)
}
let last = (total*100-resValue*100)/100
result.push(last)
return result
}

console.log(randAlloc(100,10))
回帖
  • 謓dêシ累了
    謓dêシ累了 VIP1 2020/10/15 第1楼
    来自:北京市-电信
    Uid生成:
    function uuid() {
    var s = [];
    var hexDigits = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
    for(var i = 0; i < 36; i++) {
    s[i] = hexDigits.substr(Math.floor(Math.random() * hexDigits.length), 1);
    }
    s[14] = "4"; // bits 12-15 of the time_hi_and_version field to 0010
    s[19] = hexDigits.substr((s[19] & 0x3) | 0x8, 1); // bits 6-7 of the clock_seq_hi_and_reserved to 01
    s[8] = s[13] = s[18] = s[23] = "";
    var uuid = s.join("");
    return uuid;
    }
    回复