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

发布于 2022-09-04 12:25:56 字数 1026 浏览 40 评论 0

比如将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);

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

空城之時有危險 2022-09-11 12:25:56
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 ]
夜无邪 2022-09-11 12:25:56

比如数组前7个就在12上下浮动,剩下3随机余下金额的。你这个时间不说,而且有些浪费资源。。。

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文