简单的for循环似乎无法正常工作

问题描述 投票:4回答:7

我在不重复的情况下随机获得一个从1到16的数字的数组很麻烦。我制作了num数组以放入createNum函数中的数字。

createNum函数具有一个for循环,该循环获取1到16之间的数字,直到语句将16个数字压入num数组。

最后,我运行createNum()并在网上显示数字。当我编写此代码时,它有时可以工作,但现在不起作用。

有人可以指出我在哪里犯了错误?

let num = [];

function createNum () {
    for (i = 0; i <= 15;) {
        let numGen = Math.floor(Math.random() * 15) + 1;
        if (!num.includes(numGen)) {
            num.push(numGen);
            i++;
        };
    };
}
console.log(createNum());
document.getElementById("selectedNumbersShownHere").innerHTML = num;
console.log(num);
javascript function loops push
7个回答
2
投票

这是因为Math.random()从不返回1,所以最后Math.floor(Math.random() * 15)将返回最大14​​,将其加到1将使您最大15。使用Math.ceil代替Math.floor,即

let num = [];

function createNum () {
    for (i = 0; i <=15;) {
        let numGen = Math.ceil(Math.random() * 16);
        console.log(numGen)
        if (!num.includes(numGen)) {
            num.push(numGen);
             i++;
        };
    };
}
console.log(createNum());
document.getElementById("selectedNumbersShownHere").innerHTML = num;
console.log(num);

希望有帮助!


2
投票

[for (i = 0; i <= 15;)生成16个数字,但是Math.floor(Math.random() * 15) + 1仅具有15个可能的值(1〜15)。

推荐使用shuffle功能。如果生成大尺寸的随机数组,功能将很慢。

How can I shuffle an array?


2
投票

您的循环似乎永远不会结束,因为获得最后一个值的可能性非常低,并且永远不会在短时间内发生。

加:您的公式是错误的let numGen = Math.floor(Math.random() * 15) + 1;应该是............:let numGen = Math.floor(Math.random() * 16) + 1; 值16

请参阅=> Generating random whole numbers in JavaScript in a specific range?

执行此操作:

function createNum()
  {
  let num =[], lastOne =136; // 136 = 1 +2 +3 + ... +16
  for (;;)
    {
    let numGen = Math.floor(Math.random() *16) +1;
    if (!num.includes(numGen))
      {
      lastOne -= numGen;
      if (num.push(numGen)>14) break;
      }
    }
  num.push(lastOne); // add the missing one (optimizing)
  return num;
  }

let unOrdered_16_vals = createNum();

/*
document.getElementById("selectedNumbersShownHere").textContent = unOrdered_16_vals.join('');
*/

console.log( JSON.stringify( unOrdered_16_vals ), 'length=', unOrdered_16_vals.length  );
console.log(  'in order = ', JSON.stringify( unOrdered_16_vals.sort((a,b)=>a-b) ) );

备注:push()方法将一个或多个元素添加到数组的末尾并返回数组的新长度


2
投票

代码中的问题是,您从15个可能的值中寻找16个不同的数字。

原因是Math.floor(Math.random() * 15) + 1;仅返回1到15之间的值,但是您的循环将一直运行直到您拥有16个唯一值,因此您将进入无限循环。

您基本上要实现的目标是随机洗牌一个值从1到16的数组。

具有良好性能(O(n))的一个常见解决方案是所谓的Fisher-Yates shuffle。这是基于implementation by Mike Bostock满足您要求的代码:

function shuffle(array) {
  let m = array.length, t, i;

  while (m) {
    i = Math.floor(Math.random() * m--);
    t = array[m];
    
    array[m] = array[i];
    array[i] = t;
  }

  return array;
}

// create array with values from 1 to 16
const array = Array(16).fill().map((_, i) => i + 1);

// shuffle
const shuffled = shuffle(array);

console.log(shuffled);

与您的方法以及对该问题的其他答案的方法相比,以上代码将只对随机数生成器进行15次调用,而其他代码将进行16次至无限次调用之间的任何地方(1 )


((1)在概率论中,这称为coupon collector's problem。对于值[[n为16,平均必须进行54次调用才能收集所有16个值。


1
投票

尝试这样:

let num = []; function createNum () { for (i = 0; num.length <= 17; i++) { let numGen = Math.floor(Math.random() * 16) + 1; if (!num.includes(numGen)) { num.push(numGen); }; }; } console.log(createNum()); document.getElementById("selectedNumbersShownHere").innerHTML = num; console.log(num);
请找到工作演示here

0
投票
This is an infinite loop error. Because your loop variable "i" is always less than or equal to 15. and your i++ is inside the if statement. You can achieve it in multiple ways. Below is one sample. let num = []; function createNum () { for (i = 0; i <= 15;) { let numGen = Math.floor(Math.random() * 15) + 1; if (!num.includes(numGen)) { num.push(numGen); }; i++; }; } console.log(createNum()); document.getElementById("selectedNumbersShownHere").innerHTML = num; console.log(num);

0
投票
对不起,我对此问题“充满热情”,我忍不住提出第二个答案,即恕我直言:最好!

function createNum () { let num = [] for (let len=0;len<16;) { let numGen = Math.ceil(Math.random() * 16) if (!num.includes(numGen)) { len = num.push(numGen) } } return num } let unOrdered = createNum(); console.log( JSON.stringify( unOrdered ) ); /* document.getElementById("selectedNumbersShownHere").textContent = unOrdered_16_vals.join(''); */
© www.soinside.com 2019 - 2024. All rights reserved.