7

JavaScript

我试过搜索这样的东西,但我找不到它。

这是一个简单的想法:

一种。取一个 0 到 10 之间的随机数。

湾。假设滚动的随机数是 3。

C。然后,保存数字(3)。

d。现在,再取一个 0 到 10 之间的随机数,但它不可能是 3,因为它已经出现了。

4

6 回答 6

19

一种解决方案是生成一个包含您要选择的所有值的数组(“桶”),在这种情况下,所有数字都是从 0 到 10。然后从数组中随机选择一个并将其从桶中删除。请注意,下面的示例不检查存储桶是否为空,因此如果您调用下面的函数超过 10 次,您将收到错误。

var bucket = [];

for (var i=0;i<=10;i++) {
    bucket.push(i);
}

function getRandomFromBucket() {
   var randomIndex = Math.floor(Math.random()*bucket.length);
   return bucket.splice(randomIndex, 1)[0];
}

// will pick a random number between 0 and 10, and can be called 10 times
console.log(getRandomFromBucket());
于 2012-10-20T11:05:55.617 回答
1
Var rnd = getRnd();

While(rnd != lastRnd)
  rnd = getRnd();

getRnd()生成随机数的函数在哪里。

实际上,您必须检查您当前的随机数是否在一个数组中......如果您的可能随机数列表很小,请注意无限循环。

于 2012-10-20T11:03:52.280 回答
1

使用d3

var bucket = d3.shuffle(d3.range(11));

while(bucket.length) {
  console.log(bucket.pop());
}
于 2016-11-01T16:52:44.247 回答
0

你可以使用这样的东西:

/**
* range Get an array of numbers within a range
* @param min {number} Lowest number in array
* @param max {number} Highest number in array
* @param rand {bool} Shuffle array
* @return {array}
*/
range: function( min, max, rand ) {
  var arr = ( new Array( ++max - min ) )
    .join('.').split('.')
    .map(function( v,i ){ return min + i })
  return rand
    ? arr.map(function( v ) { return [ Math.random(), v ] })
       .sort().map(function( v ) { return v[ 1 ] })
    : arr
}

并像这样使用它:

var arr = range( 1, 10, true )

现在您有一个数组,其中包含从 1 到 10 的 10 个随机顺序且从不重复的数字。所以接下来你可以这样做:

arr.forEach(function( num, i ) { 
  // do something, it will loop 10 times 
  // and num will always be a different number
  // from 1 to 10
});
于 2012-10-20T11:11:43.870 回答
0

只是为了好玩:源自@Strilles回答“桶构造函数”

function RandomBucket(from,until){
  min = (Number(from) || 0);
  max = (Number(until) || 10)+1;
  this.bucket = String(Array(max-min)).split(',').map(function(i){
     return min++;
  });

  if (!RandomBucket.prototype.get){
   RandomBucket.prototype.get = function(){
      var randomValue = 
        this.bucket.length < 2
        ? this.bucket.shift()
        : this.bucket.splice(Math.floor(Math.random()*this.bucket.length),1);
       return randomValue || 'bucket empty';
      };
  }
}

有关使用示例,请参见JsFiddle

于 2012-10-20T12:59:58.177 回答
0

大多数时候,我会坚持使用其他答案建议的方法 - 即创建一个可能性数组,创建一个随机版本,然后将前 n 个值作为您的样本(所有操作简单通用,可以不可更改地执行)。

但是,如果与您要使用的内存量相比,或者与您要绘制的随机值相比,可能性的范围很大(尽管@Strilles 解决方案使用内存,但不会随机绘制很多值,所以即使对于我下面的用例来说也可能是最好的)。

您的问题似乎建议的解决方案可能如下所示:

// select n integers from the range [from, to] (inclusive at both sides),
// don't use this approach for large values of n
// taking random values from the randomSource as needed
function randomNumbersWithoutReplacement(n, from, to, randomSource = Math.random) {
    const result = [];
    for (let i = 0; i < n; ++i) {
        // i values have already been taken
        // the +1 makes it inclusive
        const rangeWidth = to - from - i + 1

        let value = Math.floor(rangeWidth * randomSource()) + from

        // correct the value compared to the already sampled integers
        for (let j = 0; j < result.length; ++j) {
            if (result[j] <= value) {
                value++
            }
        }

        result.push(value)

        // sorting makes the correction loop simpler
        // (and it's nice to report the result sorted too)
        result.sort((a, b) => a - b)
    }
    return result
}

你为什么想要这个?

const quantumLottoNumbers = randomNumbersWithoutReplacement(6, 1, 59, quantumRandomSource)
于 2019-01-12T15:54:53.397 回答