生成0到'x'之间的唯一随机数(整数)

时间:2011-12-04 21:52:19

标签: javascript random

我需要生成一组唯一(无重复)整数,并且在0和给定数字之间。

那是:

var limit = 10;
var amount = 3;

如何使用Javascript生成1到10之间的3个唯一数字?

15 个答案:

答案 0 :(得分:69)

使用基本的Math方法:

  • Math.random()返回0到1之间的随机数(包括0,不包括1)。
  • 将此数字乘以所需的最高数字(例如10)
  • 围绕这个数字

    Math.floor(Math.random()*10) + 1
    

示例:

//Example, including customisable intervals [lower_bound, upper_bound)
var limit = 10,
    amount = 3,
    lower_bound = 1,
    upper_bound = 10,
    unique_random_numbers = [];

if (amount > limit) limit = amount; //Infinite loop if you want more unique
                                    //Natural numbers than exist in a
                                    // given range
while (unique_random_numbers.length < limit) {
    var random_number = Math.floor(Math.random()*(upper_bound - lower_bound) + lower_bound);
    if (unique_random_numbers.indexOf(random_number) == -1) { 
        // Yay! new random number
        unique_random_numbers.push( random_number );
    }
}
// unique_random_numbers is an array containing 3 unique numbers in the given range

答案 1 :(得分:19)

Math.floor(Math.random() * (limit+1))

Math.random()生成一个介于0和1之间的浮点数,Math.floor()将其舍入为整数。

通过将其乘以数字,您可以有效地设置范围0..number-1。如果您希望在num1num2的范围内生成它,请执行:

Math.floor(Math.random() * (num2-num1 + 1) + num1)

要生成更多数字,只需使用for循环并将结果放入数组或直接将其写入文档。

答案 2 :(得分:6)

function generateRange(pCount, pMin, pMax) {
    min = pMin < pMax ? pMin : pMax;
    max = pMax > pMin ? pMax : pMin;
    var resultArr = [], randNumber;
    while ( pCount > 0) {
        randNumber = Math.round(min + Math.random() * (max - min));
        if (resultArr.indexOf(randNumber) == -1) {
            resultArr.push(randNumber);
            pCount--;
        }
    }
    return resultArr;
}

根据所需的范围,返回整数的方法可以更改为:ceil(a,b],round [a,b],floor [a,b) ,(a,b)是在地板上添加1到min的问题。

答案 3 :(得分:4)

Math.floor(Math.random()*limit)+1

答案 4 :(得分:2)

for(i = 0;i <amount; i++)
{
    var randomnumber=Math.floor(Math.random()*limit)+1
    document.write(randomnumber)
}

答案 5 :(得分:2)

像这样的东西

var limit = 10;
var amount = 3;
var nums = new Array();

for(int i = 0; i < amount; i++)
{
    var add = true;
    var n = Math.round(Math.random()*limit + 1;
    for(int j = 0; j < limit.length; j++)
    {
        if(nums[j] == n)
        {
            add = false;
        }
    }
    if(add)
    {
        nums.push(n)
    }
    else
    {
        i--;
    }
}

答案 6 :(得分:2)

这是确保数字唯一的另一种算法:

  1. 生成一个从0到 x
  2. 的所有数字的数组
  3. 对数组进行随机播放,使元素按随机顺序
  4. 选择第一个 n
  5. 与产生随机数的方法相比,直到获得一个独特的方法,此方法使用更多的内存,但它具有更稳定的运行时间 - 保证在有限时间内找到结果。如果上限相对较低或者需要的数量相对较高,则此方法效果更好。

    为简单起见,我的回答使用Lodash库,但您也可以在没有该库的情况下实现上述算法。

    // assuming _ is the Lodash library
    
    // generates `amount` numbers from 0 to `upperLimit` inclusive
    function uniqueRandomInts(upperLimit, amount) {
        var possibleNumbers = _.range(upperLimit + 1);
        var shuffled = _.shuffle(possibleNumbers);
        return shuffled.slice(0, amount);
    }
    

答案 7 :(得分:2)

指出接受的答案是错误的。这是一个非重复的伪数字生成器,几乎没有内存影响,也没有O(n)问题,这对10,000,000个数字有好处。

这是一个plunkr,演示了github.com/preshing/RandomSequence这里找到的非重复伪随机生成器的javascript端口。

var RandomSequenceOfUnique = (function() {      
  function RandomSequenceOfUnique(seedBase, seedOffset) {
    var prime = 4294967291,
        residue,
        permuteQPR = function(x) {
      if (x >= prime)
        return x; 
      residue = (x * x) % prime;
      return (x <= prime / 2) ? residue : prime - residue;
    }

    this.next = function() {
      return permuteQPR((permuteQPR(this.index++) + this.intermediateOffset) ^ 0x5bf03635);
    }

    this.index = permuteQPR(permuteQPR(seedBase) + 0x682f0161);
    this.intermediateOffset = permuteQPR(permuteQPR(seedOffset) + 0x46790905);
  }
  return RandomSequenceOfUnique;
}());

构造一个实例并生成一个数字:

var generator = new RandomSequenceOfUnique(Date.now(), parseInt(Math.random() * 10000));

使用发电机:

 var num = generator.next();

这是一篇解释生成器背后的数学的文章How to Generate a Sequence of Unique Random Integers

答案 8 :(得分:1)

var randomNums = function(amount, limit) {
var result = [],
    memo = {};

while(result.length < amount) {
    var num = Math.floor((Math.random() * limit) + 1);
    if(!memo[num]) { memo[num] = num; result.push(num); };
}
return result; }

这似乎有效,并且它不断查找重复项。

答案 9 :(得分:1)

/**
 * Generates an array with numbers between
 * min and max randomly positioned.
 */
function genArr(min, max, numOfSwaps){
  var size = (max-min) + 1;
  numOfSwaps = numOfSwaps || size;
  var arr = Array.apply(null, Array(size));

  for(var i = 0, j = min; i < size & j <= max; i++, j++) {
    arr[i] = j;
  }

  for(var i = 0; i < numOfSwaps; i++) {
    var idx1 = Math.round(Math.random() * (size - 1));
    var idx2 = Math.round(Math.random() * (size - 1));

    var temp = arr[idx1];
    arr[idx1] = arr[idx2];
    arr[idx2] = temp;
  }

  return arr;
}

/* generating the array and using it to get 3 uniques numbers */
var arr = genArr(1, 10);
for(var i = 0; i < 3; i++) {
  console.log(arr.pop());
}

答案 10 :(得分:1)

我认为,这是最人性化的方法(使用while循环中的break),我在评论中解释了其机制。

function generateRandomUniqueNumbersArray (limit) {

    //we need to store these numbers somewhere
    const array = new Array();
    //how many times we added a valid number (for if statement later)
    let counter = 0;

    //we will be generating random numbers until we are satisfied
    while (true) {

        //create that number
        const newRandomNumber = Math.floor(Math.random() * limit);

        //if we do not have this number in our array, we will add it
        if (!array.includes(newRandomNumber)) {
            array.push(newRandomNumber);
            counter++;
        }

        //if we have enought of numbers, we do not need to generate them anymore
        if (counter >= limit) {
            break;
        }
    }

    //now hand over this stuff
    return array;
}

如果您需要的数字较少,您当然可以在最后的'if'语句中添加不同的限制(您的金额),但是请确保该数目小于或等于数字本身的限制-否则它将是无限的循环。

答案 11 :(得分:1)

这些答案要么不给出唯一值,要么太长了( long (甚至添加一个外部库来完成这样的简单任务)。

1 。生成一个随机数。
2 。如果我们已经有了这个随机变量,则转到 1 ,否则保留它。
3 。如果我们没有所需的随机数,请转到 1

function uniqueRandoms(qty, min, max){
  var rnd, arr=[];
  do { do { rnd=Math.floor(Math.random()*max)+min }
      while(arr.includes(rnd))
      arr.push(rnd);
  } while(arr.length<qty)
  return arr;
}

//generate 5 unique numbers between 1 and 10
console.log( uniqueRandoms(5, 1, 10) );

...以及相同功能的压缩版本:

function uniqueRandoms(qty,min,max){var a=[];do{do{r=Math.floor(Math.random()*max)+min}while(a.includes(r));a.push(r)}while(a.length<qty);return a}

答案 12 :(得分:0)

const getRandomNo = (min, max) => {
   min = Math.ceil(min);
   max = Math.floor(max);
   return Math.floor(Math.random() * (max - min + 1)) + min; 
}

此函数返回指定值之间的随机整数。该值不小于min(如果min不是整数,则下一个大于min的整数)并且小于(但不等于)max。 示例

console.log(`Random no between 0 and 10 ${getRandomNo(0,10)}`)

答案 13 :(得分:0)

这是一个简单的单行解决方案:

var limit = 10;
var amount = 3;

randoSequence(1, limit).slice(0, 3);

它使用randojs.com生成从1到10的随机随机排列的整数数组,然后截取第三个整数之后的所有内容。如果要使用此答案,请在HTML文档的head标签中扔掉它:

<script src="https://randojs.com/1.0.0.js"></script>

答案 14 :(得分:0)

作为基于 ES6 Set (“只能包含唯一值”的arr。)的另一种可能的解决方案。

用法示例:

// Get 4 unique rnd. numbers: from 0 until 4 (inclusive):
getUniqueNumbersInRange(4, 0, 5) //-> [5, 0, 4, 1];

// Get 2 unique rnd. numbers: from -1 until 2 (inclusive):
getUniqueNumbersInRange(2, -1, 2) //-> [1, -1];

// Get 0 unique rnd. numbers (empty result): from -1 until 2 (inclusive):
getUniqueNumbersInRange(0, -1, 2) //-> [];

// Get 7 unique rnd. numbers: from 1 until 7 (inclusive):
getUniqueNumbersInRange(7, 1, 7) //-> [ 3, 1, 6, 2, 7, 5, 4];

实施:

function getUniqueNumbersInRange(uniqueNumbersCount, fromInclusive, untilInclusive) {

    // 0/3. Check inputs.
    if (0 > uniqueNumbersCount) throw new Error('The number of unique numbers cannot be negative.');
    if (fromInclusive > untilInclusive) throw new Error('"From" bound "' + fromInclusive
        + '" cannot be greater than "until" bound "' + untilInclusive + '".');
    const rangeLength = untilInclusive - fromInclusive + 1;
    if (uniqueNumbersCount > rangeLength) throw new Error('The length of the range is ' + rangeLength + '=['
        + fromInclusive + '…' + untilInclusive + '] that is smaller than '
        + uniqueNumbersCount + ' (specified count of result numbers).');
    if (uniqueNumbersCount === 0) return [];


    // 1/3. Create a new "Set" – object that stores unique values of any type, whether primitive values or object references.
    // MDN - https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Set
    // Support: Google Chrome 38+(2014.10), Firefox 13+, IE 11+
    const uniqueDigits = new Set();


    // 2/3. Fill with random numbers.        
    while (uniqueNumbersCount > uniqueDigits.size) {
        // Generate and add an random integer in specified range.
        const nextRngNmb = Math.floor(Math.random() * rangeLength) + fromInclusive;
        uniqueDigits.add(nextRngNmb);
    }


    // 3/3. Convert "Set" with unique numbers into an array with "Array.from()".
    // MDN – https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/from
    // Support: Google Chrome 45+ (2015.09+), Firefox 32+, not IE
    const resArray = Array.from(uniqueDigits);
    return resArray;

}

当前实施的好处:

  1. 对输入参数进行基本的检查 –当范围太小等时,您不会得到意外的输出。
  2. 支持负范围(不仅从0开始),e。 G。从-1000到500的随机数,等等。
  3. 预期行为:如果输入范围太小,当前最受欢迎的答案将自行扩大范围(上限)。例如:获得10000个具有从0到10的指定范围的唯一数字,由于范围太小(10-0 + 1 = 11个可能的唯一数字)而需要引发错误。但是当前的最高答案会隐式地将范围扩展到10000。