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

时间:2017-12-20 06:53:42

标签: javascript performance random

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

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包含为有效字符串,即使这不是有效数字。

6 个答案:

答案 0 :(得分:3)

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

&#13;
&#13;
...
    string[] vlist = textBox1.Text.Split('\n');
    int size = (Convert.ToInt32(textBox2.Text)) / Convert.ToInt32(vlist.Length) +1;
    string newString = "";
    for(int i=0;i<size;i++){
        newString = String.Join("\n",vlist);
        textBox2.Text += newString + "\n";
    }
...
&#13;
&#13;
&#13;

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

&#13;
&#13;
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));
&#13;
&#13;
&#13;

答案 1 :(得分:1)

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

首先创建一个数组

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

现在随机播放数组

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

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

<强>演示

&#13;
&#13;
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");
&#13;
&#13;
&#13;

答案 2 :(得分: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个数字。

答案 3 :(得分:0)

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

我认为最昂贵的操作是散列表查找/插入,所以只需在没有它的情况下进行操作。

答案 4 :(得分:0)

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

答案 5 :(得分:0)

ftp://myftp.co/Media_EBOOK/EBook_Journal_Magazine/Ebooks/Computer_Science/Linux_Unix/VPN/Huawei_Technologies_MPLS_VPN_030410.pp电话中有一个可能会失去表演的地方 这是一个相当昂贵的电话,而且你正在多次调用它来生成你的字符串。

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

&#13;
&#13;
Math.random()
&#13;
&#13;
&#13;