【问题标题】:Generate 1000 random 10 digit number using javascript in a loop在循环中使用 javascript 生成 1000 个随机 10 位数字
【发布时间】:2012-04-20 00:48:32
【问题描述】:

我想使用 10 位生成至少 1000 个唯一随机数 循环中的javascript。这可能吗?或者 Javascript 是错误的做法吗?

更新:您将如何确保不会创建重复项?

【问题讨论】:

  • 是的,这在 JavaScript 中是可能的。
  • 是的,这是可能的。你想要提示吗?

标签: javascript loops random


【解决方案1】:

我会这样做:

var arr = [],
    track = [],
    min = 1000000000,
    max = 9999999999,
    qty = 1000,
    ii = 0,
    rnd;

while (ii < qty) {
    rnd = Math.floor(Math.random() * (max - min + 1)) + min;
    if (!track[rnd]) {
        arr[ii] = track[rnd] = rnd;
        ii += 1;
    }
}

这是一个工作示例:http://jsfiddle.net/mTmEs/

现在,如果 Math.random 出现问题并且由于某种原因会生成大量重复项,则此代码可能需要很长时间才能完成。不过,当您谈论大量唯一随机数时,我认为没有任何办法可以解决这种潜在问题。

【讨论】:

  • 我会将 track 更改为 Object,现在 track 是一个包含 AWFUL 很多元素的数组。使用对象会更快。
  • 您在我的测试中的方法需要 8-9 毫秒,使用一个带有循环的数组来检查重复项需要 40-50 毫秒,并且使用一个对象并从中恢复一个 10 位数字的数组需要90+ 毫秒。
  • @Creynders:Fish 使用数组的方式,和使用非数组对象完全一样;没有速度差异。他/她根本没有使用它的数组风格,当然,JavaScript 数组 are just objects,不是真正的数组。
  • @T.J.Crowder 你说的很对,只是做了一个小测试,速度没有实质性差异。我的立场是正确的。
【解决方案2】:

是的,这是可能的。

  1. 使用Math.random 生成伪随机数。 Math.random 返回一个大于或等于 0 且小于 1 的伪随机数,因此要获得一个 10 位数字(我假设是一个整数),您可以将其乘以 1,000,000,000 和用Math.roundMath.floor 将其四舍五入。 (如果您需要它们全部为 10 位数,请进行相应调整 - 添加一个基本金额,乘以一个更高的数字等)

  2. 使用对象来跟踪它们,所以从var obj = {};开始。

  3. 将数字作为键存储在对象中,例如obj[number] = true

  4. 使用if (obj[number])测试对象是否有生成的数字

  5. 循环直到获得正确数量的唯一编号。

我使用对象来存储数字的原因是 JavaScript 对象本质上是映射,并且引擎经过优化可以快速从对象中检索属性。在幕后,一个实现可以做它喜欢做的事,但可能会使用哈希表或类似的东西。

请注意,没有必要为此使用“数组”; JavaScript arrays aren't really arrays,它们只是具有几个特殊功能的对象。

【讨论】:

  • 乘以 1,000,000,000 并不能保证 10 位数字
  • @Balaswamyvaddeman:我认为他的意思是或更少的 10 位数字。 (您的反对票,还是其他人的反对票?对于这么小的缺陷似乎相当强大。)
  • 我同意 10 位数字包括左侧填充 0 的较小数字。我想这取决于你是否认为 01 是一个两位数。
【解决方案3】:

您可以在 JS 中执行此操作,但您必须检查数组以查看它是否包含当前生成的随机数。这显然会降低性能。

看看这些答案是否有帮助。

Random number generator that fills an interval

Generate unique random numbers between 1 and 100

【讨论】:

    【解决方案4】:

    生成 n 个长度为 l 的随机数的通用函数可能是:

    // Generate n unique random numbers of length l
    // l should be less than 15
    function genNRandLen(n, l) {
    
      // Make sure l and n are numbers
      n = Number(n);
      l = Number(l);
    
      // Protect against bad input
      if (isNaN(l) || isNaN(n)) return;
    
      var o = {}, a = [], num;
      var min = l == 1? 0 : Math.pow(10, l-1);
      var r = Math.pow(10, l) - min;
    
      // Protect against endless loop
      if (n >= (r)) return;
    
      while (n--) {
        do {
          num = Math.floor(min + (Math.random()*r));
        } while (o[num])
    
        o[num] = true;
        a[n] = num;
      }
      return a.sort();
    }
    

    排序只是为了便于在测试时查看重复项,如果不需要则删除或首选随机顺序。

    如果需要超过 15 位的数字,可以通过连接较短随机数的字符串并修剪到所需长度来创建它们。以下将生成任意长度的随机数:

    // Generate random number of length l
    function randLen(l) {
      var n = '';
      while (n.length < l) {
        n += String(Math.random()).replace(/^0\.0*/,'');
      }
      return n.substring(0, l);
    }
    

    它必须返回一个字符串,因为转换为数字会弄乱结果。哦,所有的数字都是整数。

    【讨论】:

      【解决方案5】:

      为什么不呢?代码如下:

      var a=[]; 
      for (var i=1000; i--;) 
       a.push(Math.random()*10000000000)
      

      【讨论】:

      • 我相信这有可能造成重复。
      • 这并不能保证数字有 10 位。
      • 是的,我同意你们俩的观点。但是对于这个特定的任务来说可能没问题。其他检查只是不必要的麻烦。
      • 没有。该问题专门说唯一随机数。
      猜你喜欢
      • 1970-01-01
      • 2014-02-14
      • 1970-01-01
      • 1970-01-01
      • 2010-09-07
      • 2011-10-26
      • 1970-01-01
      • 2018-05-20
      相关资源
      最近更新 更多