javascript - 将一个数随机分配(微信红包算法)

查看:352
本文介绍了javascript - 将一个数随机分配(微信红包算法)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

问 题

比如将100随机分配为10个,最小1,最大12
PS:下面是我的实现方式(先生成一个10个数的数组,每个数组元素都是1,然后再进入循环,随机生成一个数组下标进行 +1,如果当前数组元素超过最大数12则不进行叠加)

/ 最小1%, 最大12% /

        function ranAllo(value, min, max, length) {

            var ran = [], arrId;

            //循环存放数组最小值
            for(var i = 0; i < length; i++) {
                
                ran[i] = min;
                
            }
            
            //计算剩下的值
            var spare = value - (min * length);
            
            while(spare > 0) {
                
                //生成数组随机ID
                arrId = Math.round(Math.random() * length);

                if(ran[arrId] < max) {
                    
                    ran[arrId] += 1;
                    
                    spare--;
                    
                }
                
            }
            
            console.log(ran);
            
            return ran

        }

ranAllo(100, 1, 12, 10);

但是这种实现方式的性能比较低,请问有没有其他比较好的实现方式

解决方案

function randAlloc(total, min, max, length) {
    // 首先要判断是否符合 min 和 max 条件
    if (min * length > total || max * length < total) {
        throw Error(`没法满足最最少 ${min} 最大 ${max} 的条件`);
    }

    const result = [];
    let restValue = total;
    let restLength = length;
    for (let i = 0; i < length - 1; i++) {
         restLength--;
        // 这一次要发的数量必须保证剩下的要足最小量
        // 同进要保证剩下的不能大于需要的最大量
        const restMin = restLength * min;
        const restMax = restLength * max;
        // 可发的量
        const usable = restValue - restMin;
        // 最少要发的量
        const minValue = Math.max(min, restValue - restMax);
        // 以 minValue 为最左,max 为中线来进行随机,即随机范围是 (max - minValue) * 2
        // 如果这个范围大于 usable - minValue,取 usable - minValue
        const limit = Math.min(usable - minValue, (max - minValue) * 2);
        // 随机部分加上最少要发的部分就是应该发的,但是如果大于 max,最大取到 max
        result[i] = Math.min(max, minValue + Math.floor(limit * Math.random()));
        restValue -= result[i];
    }
    result[length - 1] = restValue;

    return result;
}

for (let i = 0; i < 5; i++) {
    console.log(randAlloc(100, 1, 12, 10));
}

运行结果(还真有背时运气的,才得1)

[ 3, 6, 9, 11, 12, 11, 12, 12, 12, 12 ]
[ 5, 4, 12, 12, 12, 8, 11, 12, 12, 12 ]
[ 1, 12, 12, 12, 6, 9, 12, 12, 12, 12 ]
[ 12, 7, 12, 12, 12, 3, 12, 7, 12, 11 ]
[ 4, 11, 5, 12, 12, 12, 10, 10, 12, 12 ]

这篇关于javascript - 将一个数随机分配(微信红包算法)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆