繁体   English   中英

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

[英]Simple for loop does not seem work properly

我在不重复的情况下随机获取一个包含 1 到 16 数字的数组时遇到了麻烦。 我制作了num数组来放置来自createNum函数的数字。

createNum函数有一个 for 循环,它获取从 1 到 16 的数字,直到 if 语句将 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);

您的循环似乎永远不会完成,因为获得最后一个值的概率非常低,而且永远不会在短时间内发生。

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

请参阅 => 在 JavaScript 中生成特定范围内的随机整数?

做这个:

 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)=>ab) ) );

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

这是因为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);

希望能帮助到你!

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

推荐使用shuffle功能。 如果你生成一个大尺寸的混洗数组,你的函数会很慢。

我怎样才能洗牌一个数组?

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

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

您基本上想要实现的是随机打乱一个值为 1 到 16 的数组。

一种具有良好性能 ( O(n) ) 的常见解决方案是所谓的Fisher-Yates shuffle 以下是根据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)在概率论中,这称为优惠券收集者问题 对于 16 的值n ,平均必须进行 54 次调用才能收集所有 16 个值。

像这样尝试:

    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);

请在此处找到工作演示

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);

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

 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(''); */

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM