【问题标题】:Random non-repeating number generation in javascript between two limitsjavascript中两个限制之间的随机非重复数字生成
【发布时间】:2013-05-24 05:37:49
【问题描述】:

除了数组拼接之外,还有什么方法可以用来在两个数字之间生成一个随机数而不重复,直到生成这两个数字之间的所有数字?除了拼接之外,改组技术或任何其他数组方法都非常有用。

【问题讨论】:

标签: javascript


【解决方案1】:

首先我们使用 FisherYates 实现 (credit goes to @ChristopheD) 并扩展数组原型以提供 shuffle 函数

function arrayShuffle () {
   var i = this.length, j, temp;
   if ( i === 0 ) return false;
   while ( --i ) {
      j = Math.floor( Math.random() * ( i + 1 ) );
      temp = this[i];
      this[i] = this[j]; 
      this[j] = temp;
   }
}

Array.prototype.shuffle =arrayShuffle;

var numbers = new Array(0, 1, 2, 3, 4, 5, 6, 7, 8, 9);
numbers.shuffle();

现在使用pop 方法,我们从种子中获取一个数字,直到它为空

numbers.pop(); //returns a number

为了确保我们有一个填充了startend 范围内数字的数组,我们使用一个简单的循环来创建我们的种子。

var start = 1;
var end = 5;
var numbers = new Array();
for (var i = start; i <= end; i++) {
    numbers.push(i);
}

这是jsfiddle上的示例

更新:让 fisherYates 算法更高效地洗牌

【讨论】:

  • 这是一个糟糕的(非均匀)洗牌算法。要看到它不可能是一个统一的改组,只需考虑有N**N同样可能的改组,而N元素的排列数量是N!,并且通常N**N不是N!的精确倍数.
  • 这不是正确的洗牌方式。查找 Fisher-Yates 洗牌。您只能稍后在列表中随机播放每个成员。这样你就得到了 n!可能的排列,这是每个恰好命中一次的正确数字。
  • 亲爱的主,这不应该是一个学术解决方案。但是看在上帝的份上,我放了一个更有效的洗牌算法:)
  • @MatthaisLaug 您的洗牌算法不正确。就像,它是有偏见的。例如,它并没有同样频繁地选择所有洗牌。这就是我们所抱怨的,因为缺乏正确性是非常糟糕的:)
  • fisterYates is an algorithm for generating a random permutation of a finite set—in plain terms, for randomly shuffling the set 但可能会发生,在所有排列出现之前,您再次获得相同的排列。如果要避免这种情况,则需要向 shuffle 方法提供一个数组数组,以检查新的 shuffle 数组是否尚未使用
【解决方案2】:

在处理较小的数组时,我通常做的是随机排序数组:

yourArray.sort(function() { return 0.5 - Math.random() });

【讨论】:

    【解决方案3】:

    试试这个http://jsbin.com/imukuh/1/edit:

    function randRange(min, max) {
      var result = [];
      for (var i=min; i<=max; i++) result.push(i);
      return result.map(function(v){ return [Math.random(), v] })
        .sort().map(function(v){ return v[1] });
    }
    
    console.log(randRange(1,5));
    // [4, 3, 1, 5, 2]
    // [3, 5, 2, 4, 1]
    // [1, 5, 2, 3, 4]
    // [3, 2, 5, 1, 4]
    // ...
    

    【讨论】:

      猜你喜欢
      • 2014-12-19
      • 2020-02-02
      • 2014-10-02
      • 2019-10-18
      • 2014-03-20
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多