Javascript 生成1到100之间的唯一随机数

Javascript 生成1到100之间的唯一随机数,javascript,random,integer,numbers,Javascript,Random,Integer,Numbers,如何使用JavaScript生成一些介于1和100之间的唯一随机数字?生成100个数字的排列,然后依次选择 使用 JavaScript: function fisherYates ( myArray,stop_count ) { var i = myArray.length; if ( i == 0 ) return false; int c = 0; while ( --i ) { var j = Math.floor( Math.random() * ( i +

如何使用JavaScript生成一些介于1和100之间的唯一随机数字?

生成100个数字的排列,然后依次选择

使用

JavaScript:

  function fisherYates ( myArray,stop_count ) {
  var i = myArray.length;
  if ( i == 0 ) return false;
  int c = 0;
  while ( --i ) {
     var j = Math.floor( Math.random() * ( i + 1 ) );
     var tempi = myArray[i];
     var tempj = myArray[j];
     myArray[i] = tempj;
     myArray[j] = tempi;

     // Edited thanks to Frerich Raabe
     c++;
     if(c == stop_count)return;

   }
}

编辑

改进代码:

function fisherYates(myArray,nb_picks)
{
    for (i = myArray.length-1; i > 1  ; i--)
    {
        var r = Math.floor(Math.random()*i);
        var t = myArray[i];
        myArray[i] = myArray[r];
        myArray[r] = t;
    }

    return myArray.slice(0,nb_picks);
}
潜在问题:

假设我们有100个数字的数组{e.g.[1,2,3…100]},我们在8次交换后停止交换; 然后大部分时间数组看起来像{1,2,3,76,5,6,7,8,…这里的数字将被洗牌…10}

因为每个数字都会以1/100的概率交换,所以 问题。交换前8个数字的概率为8/100,而。替换其他92的比例为92/100

但若我们运行完整数组的算法,那个么我们可以确定(几乎)每个条目都被交换了

否则我们将面临一个问题:选择哪8个数字

  • 用数字1到100填充数组
  • 取结果数组的前8个元素

  • 例如:要生成8个唯一的随机数并将其存储到数组中,只需执行以下操作:

    var arr=[];
    而(平均长度<8){
    var r=Math.floor(Math.random()*100)+1;
    if(arr.indexOf(r)==-1)arr.push(r);
    }
    
    控制台日志(arr)与机器魔术师相同的置换算法,但具有原型实现。更适合大量采摘。如果可用,请使用

    // swaps elements at index i and j in array this
    // swapping is easy on js 1.7 (feature detection)
    Array.prototype.swap = (function () {
        var i=0, j=1;
        try { [i,j]=[j,i]; }
        catch (e) {}
        if(i) {
            return function(i,j) {
                [this[i],this[j]] = [this[j],this[i]];
                return this;
            }
        } else {
            return function(i,j) {
                var temp = this[i];
                this[i] = this[j];
                this[j] = temp;
                return this;
            }
        }
    })();
    
    
    // shuffles array this
    Array.prototype.shuffle = function() {
        for(var i=this.length; i>1; i--) {
            this.swap(i-1, Math.floor(i*Math.random()));
        }
        return this;
    }
    
    // returns n unique random numbers between min and max
    function pick(n, min, max) {
        var a = [], i = max;
        while(i >= min) a.push(i--);
        return a.shuffle().slice(0,n);
    }
    
    pick(8,1,100);
    
    编辑: 根据白鲸鲍勃的回答,另一个命题更适合于少量选择。为了保证唯一性,我们从数组中删除拾取的数字

    // removes n random elements from array this
    // and returns them
    Array.prototype.pick = function(n) {
        if(!n || !this.length) return [];
        var i = Math.floor(this.length*Math.random());
        return this.splice(i,1).concat(this.pick(n-1));
    }
    
    // returns n unique random numbers between min and max
    function pick(n, min, max) {
        var a = [], i = max;
        while(i >= min) a.push(i--);
        return a.pick(n);
    }
    
    pick(8,1,100);
    
    我会这样做:

    function randomInt(min, max) {
        return Math.round(min + Math.random()*(max-min));
    }
    var index = {}, numbers = [];
    for (var i=0; i<8; ++i) {
        var number;
        do {
            number = randomInt(1, 100);
        } while (index.hasOwnProperty("_"+number));
        index["_"+number] = true;
        numbers.push(number);
    }
    delete index;
    
    函数randomInt(最小值,最大值){
    返回Math.round(min+Math.random()*(max-min));
    }
    变量索引={},数字=[];
    对于(var i=0;i如何使用?这样,您的最佳方案是只随机8次。只有在您想要数字范围的一小部分时,它才会有效。它也比Fisher Yates占用的内存少很多,因为您不必为数组分配空间

    var ht={}, i=rands=8;
    while ( i>0 || keys(ht).length<rands) ht[Math.ceil(Math.random()*100)]=i--;
    alert(keys(ht));
    

    为了避免任何长时间和不可靠的洗牌,我将执行以下操作

  • 按顺序生成包含介于1和100之间的数字的数组
  • 生成一个介于1和100之间的随机数
  • 在数组中查找此索引处的数字并存储在结果中
  • 从数组中删除元素,使其短一个
  • 重复步骤2,但使用99作为随机数的上限
  • 重复步骤2,但使用98作为随机数的上限
  • 重复步骤2,但使用97作为随机数的上限
  • 重复步骤2,但使用96作为随机数的上限
  • 重复步骤2,但使用95作为随机数的上限
  • 重复步骤2,但使用94作为随机数的上限
  • 重复步骤2,但使用93作为随机数的上限
  • 瞧,没有重复的数字

    var bombout=0;
    var checkArr=[];
    var arr=[];
    while(arr.length < 8 && bombout<100){
      bombout++;
      var randomNumber=Math.ceil(Math.random()*100);
      if(typeof checkArr[randomNumber] == "undefined"){
        checkArr[randomNumber]=1;
        arr.push(randomNumber);
      }
    }​
    
    // untested - hence bombout
    
    如果有人感兴趣的话,我可以稍后发布一些实际的代码

    编辑:这可能是我的竞争优势,但看过@Alsciende的帖子后,我忍不住发布了我承诺的代码

    <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
    <html>
    <head>
    <title>8 unique random number between 1 and 100</title>
    <script type="text/javascript" language="Javascript">
        function pick(n, min, max){
            var values = [], i = max;
            while(i >= min) values.push(i--);
            var results = [];
            var maxIndex = max;
            for(i=1; i <= n; i++){
                maxIndex--;
                var index = Math.floor(maxIndex * Math.random());
                results.push(values[index]);
                values[index] = values[maxIndex];
            }
            return results;
        }
        function go(){
            var running = true;
            do{
                if(!confirm(pick(8, 1, 100).sort(function(a,b){return a - b;}))){
                    running = false;
                }
            }while(running)
        }
    </script>
    </head>
    
    <body>
        <h1>8 unique random number between 1 and 100</h1>
        <p><button onclick="go()">Click me</button> to start generating numbers.</p>
        <p>When the numbers appear, click OK to generate another set, or Cancel to stop.</p>
    </body>
    
    
    8介于1和100之间的唯一随机数
    函数拾取(n、最小值、最大值){
    var值=[],i=最大值;
    而(i>=min)值。推(i--);
    var结果=[];
    var maxIndex=最大值;
    
    对于(i=1;i而言,将数字从1洗牌到100洗牌是正确的基本策略,但如果只需要8个洗牌数字,则无需将所有100个数字洗牌

    我对Javascript不太了解,但我相信快速创建一个包含100个null的数组很容易。然后,在8轮中,交换数组的第n个元素(n从0开始)使用从n+1到99之间随机选择的元素。当然,任何尚未填充的元素都意味着该元素实际上是原始索引加1,因此这很容易考虑。完成8轮后,数组的前8个元素将有8个随机数字。

    var bombout=0;
    
    var bombout=0;
    var checkArr=[];
    var arr=[];
    while(arr.length < 8 && bombout<100){
      bombout++;
      var randomNumber=Math.ceil(Math.random()*100);
      if(typeof checkArr[randomNumber] == "undefined"){
        checkArr[randomNumber]=1;
        arr.push(randomNumber);
      }
    }​
    
    // untested - hence bombout
    
    var checkArr=[]; var-arr=[];
    while(arr.length<8&&bombout如果需要更唯一的数组,则必须生成一个数组(1..100)

    var arr=[];
    函数生成器域(){
    
    对于(var i=1;i对于具有类似于
    [,2,4,6,7,,]的孔的阵列
    
    因为我的问题是填补这些漏洞。所以我根据需要对其进行了修改:)

    以下修改后的解决方案对我有效:)

    var arr=[,2,,4,,6,7,,];//示例
    而(arr.length<9){
    var randomnumber=Math.floor(Math.random()*9+1);
    var=false;
    
    对于(var i=0;i使用JavaScript 1.6 indexOf函数添加同一代码的另一个更好版本(可接受的答案)。无需在每次检查副本时循环整个数组

    var arr = []
    while(arr.length < 8){
      var randomnumber=Math.ceil(Math.random()*100)
      var found=false;
        if(arr.indexOf(randomnumber) > -1){found=true;}
      if(!found)arr[arr.length]=randomnumber;
    }
    
    var arr=[]
    而(平均长度<8){
    var randomnumber=Math.ceil(Math.random()*100)
    var=false;
    如果(arr.indexOf(randomnumber)>-1){found=true;}
    如果(!found)arr[arr.length]=随机数;
    }
    
    旧版本的Javascript仍然可以使用顶部的版本


    PS:尝试建议更新wiki,但被拒绝。我仍然认为它可能对其他人有用。

    这是我的个人解决方案:

    <script>
    
    var i, k;
    var numbers = new Array();
    k = Math.floor((Math.random()*8));
    numbers[0]=k;
        for (var j=1;j<8;j++){
            k = Math.floor((Math.random()*8));
    i=0;
    while (i < numbers.length){
    if (numbers[i] == k){
        k = Math.floor((Math.random()*8));
        i=0;
    }else {i++;}
    }
    numbers[j]=k;
        }
        for (var j=0;j<8;j++){
    alert (numbers[j]);
        }
    </script>
    
    
    变量i,k;
    变量编号=新数组();
    k=数学楼层((数学随机()*8));
    数字[0]=k;
    
    对于(var j=1;j最好的早期答案是由
    sje397
    给出的答案。您将尽可能快地获得尽可能好的随机数

    我的解决方案与他的解决方案非常相似。但是,有时你需要随机顺序的随机数,这就是我决定发布答案的原因。此外,我提供了一个通用函数

    function selectKOutOfN(k, n) {
      if (k>n) throw "k>n";
      var selection = [];
      var sorted = [];
      for (var i = 0; i < k; i++) {
        var rand = Math.floor(Math.random()*(n - i));
        for (var j = 0; j < i; j++) {
          if (sorted[j]<=rand)
            rand++;
          else
            break;
        }
        selection.push(rand);
        sorted.splice(j, 0, rand);
      }
      return selection;
    }
    
    alert(selectKOutOfN(8, 100));
    
    函数选择koutofn(k,n){
    如果(k>n)抛出“k>n”;
    var选择=[];
    var排序=[];
    对于(变量i=0;i<script>
    
    var i, k;
    var numbers = new Array();
    k = Math.floor((Math.random()*8));
    numbers[0]=k;
        for (var j=1;j<8;j++){
            k = Math.floor((Math.random()*8));
    i=0;
    while (i < numbers.length){
    if (numbers[i] == k){
        k = Math.floor((Math.random()*8));
        i=0;
    }else {i++;}
    }
    numbers[j]=k;
        }
        for (var j=0;j<8;j++){
    alert (numbers[j]);
        }
    </script>
    
    function selectKOutOfN(k, n) {
      if (k>n) throw "k>n";
      var selection = [];
      var sorted = [];
      for (var i = 0; i < k; i++) {
        var rand = Math.floor(Math.random()*(n - i));
        for (var j = 0; j < i; j++) {
          if (sorted[j]<=rand)
            rand++;
          else
            break;
        }
        selection.push(rand);
        sorted.splice(j, 0, rand);
      }
      return selection;
    }
    
    alert(selectKOutOfN(8, 100));
    
    function getUniqueRandomNos() {
        var indexedArrayOfRandomNo = [];
        for (var i = 0; i < 100; i++) {
            var randNo = Math.random();
            indexedArrayOfRandomNo.push([i, randNo]);
        }
        indexedArrayOfRandomNo.sort(function (arr1, arr2) {
            return arr1[1] - arr2[1]
        });
        var uniqueRandNoArray = [];
        for (i = 0; i < 8; i++) {
            uniqueRandNoArray.push(indexedArrayOfRandomNo[i][0]);
        }
        return uniqueRandNoArray;
    }
    
    /* Creates an array of random integers between the range specified 
         len = length of the array you want to generate
         min = min value you require
         max = max value you require
         unique = whether you want unique or not (assume 'true' for this answer)
    */
        function _arrayRandom(len, min, max, unique) {
            var len = (len) ? len : 10,
                    min = (min !== undefined) ? min : 1,
                    max = (max !== undefined) ? max : 100,
                    unique = (unique) ? unique : false,
                    toReturn = [], tempObj = {}, i = 0;
    
            if(unique === true) {
                for(; i < len; i++) {
                    var randomInt = Math.floor(Math.random() * ((max - min) + min));
                    if(tempObj['key_'+ randomInt] === undefined) {
                        tempObj['key_'+ randomInt] = randomInt;
                        toReturn.push(randomInt);
                    } else {
                        i--;
                    }
                }
            } else {
                for(; i < len; i++) {
                    toReturn.push(Math.floor(Math.random() * ((max - min) + min)));
                }
            }
    
            return toReturn;
        }
    
    _arrayRandom(8, 1, 100, true);
    
    var arr = []
    while(arr.length < 8){
      var randomnumber=Math.ceil(Math.random()*100)
      if(arr.indexOf(randomnumber) === -1){arr.push(randomnumber)}  
    }
    document.write(arr);
    
     var generatedNumbers = [];
    
        function generateRandomNumber(precision) { // input --> number precision in integer 
            if (precision <= 20) {
                var randomNum = Math.round(Math.random().toFixed(precision) * Math.pow(10, precision));
                if (generatedNumbers.indexOf(randomNum) > -1) {
                    if (generatedNumbers.length == Math.pow(10, precision))
                        return "Generated all values with this precision";
                        return generateRandomNumber(precision);
                } else {
                    generatedNumbers.push(randomNum);
                    return randomNum;
                }
            } else
               return "Number Precision shoould not exceed 20";
        }
        generateRandomNumber(1);
    
    function uniqueArray(minRange, maxRange, arrayLength) {
      var arrayLength = (arrayLength) ? arrayLength : 10
      var minRange = (minRange !== undefined) ? minRange : 1
      var maxRange = (maxRange !== undefined) ? maxRange : 100
      var numberOfItemsInArray = 0
      var hash = {}
      var array = []
    
      if ( arrayLength > (maxRange - minRange) ) throw new Error('Cannot generate unique array: Array length too high')
    
      while(numberOfItemsInArray < arrayLength){
        // var randomNumber = Math.floor(Math.random() * (maxRange - minRange + 1) + minRange)
        // following line used for performance benefits
        var randomNumber = (Math.random() * (maxRange - minRange + 1) + minRange) << 0
    
        if (!hash[randomNumber]) {
          hash[randomNumber] = true
          array.push(randomNumber)
          numberOfItemsInArray++
        }
      }
      return array
    }
    document.write(uniqueArray(1, 100, 8))
    
    getRandom (min, max) {
      return Math.floor(Math.random() * (max - min)) + min
    }
    
    getNRandom (min, max, n) {
      const numbers = []
      if (min > max) {
        return new Error('Max is gt min')
      }
    
      if (min === max) {
        return [min]
      }
    
      if ((max - min) >= n) {
        while (numbers.length < n) {
          let rand = this.getRandom(min, max + 1)
          if (numbers.indexOf(rand) === -1) {
            numbers.push(rand)
          }
        }
      }
    
      if ((max - min) < n) {
        for (let i = min; i <= max; i++) {
          numbers.push(i)
        }
      }
      return numbers
    }
    
    let finals = [];
    const count = 5; // Considering 5 numbers
    const max = 100;
    
    for(let i = 0; i < max; i++){
      const rand = Math.round(Math.random() * max);
      !finals.includes(rand) && finals.push(rand)
    }
    
    finals = finals.slice(0, count)