我在不重复的情况下随机获得一个从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);
这是因为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
功能。如果生成大尺寸的随机数组,功能将很慢。
您的循环似乎永远不会结束,因为获得最后一个值的可能性非常低,并且永远不会在短时间内发生。
加:您的公式是错误的: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()
方法将一个或多个元素添加到数组的末尾并返回数组的新长度。
代码中的问题是,您从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个值。
尝试这样:
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
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('');
*/