javascript - 将一个数随机分配(微信红包算法)
本文介绍了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屋!
查看全文