在JavaScript中生成大量独特的小随机数的最快方法

问题描述 投票:2回答:6

想知道如何快速生成大量独特的小型随机数。当我像这样实现它时,它似乎成倍地减速,直到它永远不会完成,或者需要数小时才能完成。可能是因为它最终会产生大量重复。

var intsmap = {}
var intsarray = []
var i = 100000
while (i--) {
  var int = randominteger(6)
  if (intsmap[int]) i++
  else {
    intsmap[int] = true
    intsarray.push(int)
  }
}
// return intsarray

function randominteger(exp) {
  var string = rand(exp)
  return pad(string, exp)
}

function pad(num, size) {
  var s = rand(9) + num
  return s.substr(s.length - size)
}

function rand(exp) {
  var integer = Math.random() * Math.pow(10, exp) << 0
  var string = toString(integer, '0123456789')
  return string
}

function toString(value, code) {
  var digit
  var radix = code.length
  var result = ''

  do {
    digit = value % radix
    result = code[digit] + result
    value = Math.floor(value / radix)
  } while (value)

  return result
}

想知道如何实现这一点,但如果可能的话,代码可以在几秒钟内完成。

更新

  • 我希望这组数字在任意范围内均匀分布(在这个例子中,1000000个字符串,不一定是0-1000000,例如可能是5050000)。
  • 我想数字不一定是有效数字,只是一串整数。因此,例如,他们可以将01010101包含为有效字符串,即使这不是有效数字。
javascript performance random
6个回答
3
投票

您可以将对象用作查找,并仅插入唯一的随机数

var intsmap = {};
var i = 100000;
while (i--) {
  var int = Math.random() * Math.pow(10, 6) << 0;
  if(intsmap[int])
    continue;
  else
    intsmap[int] = true;
}

console.log(Object.keys(intsmap));

在给定范围内生成数字后,您也可以使用Durstenfeld shuffle。

var arr = Array.from({length:1000000}, (_,i) => (i+1));

function shuffleArray(array) {
    for (var i = array.length - 1; i > 0; i--) {
        var j = Math.floor(Math.random() * (i + 1));
        [array[i], array[j]] = [array[j], array[i]];
    }
}
shuffleArray(arr);
console.log(arr);

1
投票

只是尝试将数字1的数组洗牌到maxNum

首先创建一个数组

var maxNum = 1000000;
var arr = Array(maxNum).fill().map((e,i)=>i+1);

现在洗牌阵列

arr.sort(function() {
  return .5 - Math.random();
});

现在你有了一系列独特的随机数

演示

var startTime = new Date().getTime();

var maxNum = 1000000;
var arr = Array(maxNum).fill().map((e, i) => i + 1);

arr.sort(function() {
  return .5 - Math.random();
});

var endTime = new Date().getTime();
console.log( "Time taken to get " + maxNum + " size random unique number is " + ( endTime - startTime ) + " ms");

1
投票

我可以提出这种方法:

  • 生成一个随机数
  • 把它变成一个字符串(0.1234567812345678)
  • 并提取长度为10的6个子串

码:

var res = {},
    s = "";
for (let i=0; i<1000000; ++i) {
    s = Math.random().toString();
    for (let j=0; j<6; ++j) {
        res[s.substring(2+j, 12+j)] = true; // extract 10 digits
    }
}

经过1,000,000次迭代后,您计算出6,000,000个数字且碰撞非常少(平均为1,800个)。因此,您可以在几秒钟内获得1,000,000个数字甚至更多。


0
投票

如果你需要独特的大阵列尝试以其他方式思考。只需创建范围0 ... 100000并将其随机播放并应用此数组所需的功能。


0
投票
 var acc = 0;
 const result = [];
 for(var i = 0; i < 100000; i++)
   result.push(acc += Math.floor(Math.random() * 10) + 1);

我认为最昂贵的操作是哈希表查找/插入,所以不用它就可以做到。


0
投票

你可能会失去表演的地方是我打电话的qazxsw。 这是一个相当昂贵的电话,你要多次调用它来生成你的字符串。

利用它的一个解决方案是从Math.random的单个结果中获取整个字符串。

Math.random()
© www.soinside.com 2019 - 2024. All rights reserved.