Javascipt 嵌套 While 循环未结束

xiaobai5883

我想生成 5 组不同的 2 个不同的数字(范围从 0 到 9)。

这是我的代码,但似乎不停地执行。有人可以帮忙吗?先感谢您。

let numPos = [];
let numPosTemp = [];
let r, j, k;

// generate 5 sets
while (numPos.length < 5) {

   // generate 2 diff num pos
   while (numPosTemp.length < 2) {
      r = Math.floor(Math.random() * 10);
      if (numPosTemp.indexOf(r) === -1) {
         numPosTemp.push(r);
      }
   }

   // check match any child array
   k = 0;
   for (j = 0; j < numPos.length; j++) {
      if (numPosTemp.every(function (element) {
         return numPos[j].includes(element);
      }) == true) {
      k++;
      }
   }

   // will only add into numPos if totally no match
   if (k == 0) {
      numPos.push(numPosTemp);
   }
}

如果有其他更好或更有效的方法也请发表评论..谢谢~!

更新:样本输出:[[0, 1], [2, 3], [6, 9], [4, 2], [7, 8]]

尼克帕森斯

你有一个无限循环,因为numPosTemp在你的 while 循环的第一次迭代之后,你的循环的下一次迭代将保留两个元素。因此,您的内部 while 循环不会运行,因为numPostTemp它已经大于/等于 2。for循环中的if 语句检查也是如此,因为您正在检查您刚刚推入的数组是否numPos存在于numPos. 这会导致k增加,因此您最终的 if 语句检查为假。由于您的循环的这次迭代没有任何变化,您最终会陷入无限循环,因为numPos无法增加。要解决此问题,请numPosTemp进入您的 while 循环。

此外,您的.every()方法正在检查您当前的所有元素是否numPosTemp存在于您的numPos数组中。如果一个元素不存在,则 every 方法将返回 valse 并且您的numPosTemp数组仍将被添加,这意味着[1, 2], [1, 3]可能会发生。要解决此问题(因此 1 不会加倍),请更改.every().some()

let numPos = [];
let r, j, k;

// generate 5 sets
while (numPos.length < 5) {
   let numPosTemp = [];
   // generate 2 diff num pos
   while (numPosTemp.length < 2) {
      r = Math.floor(Math.random() * 10);
      if (numPosTemp.indexOf(r) === -1) {
         numPosTemp.push(r);
      }
   }

   // check match any child array
   k = 0;
   for (j = 0; j < numPos.length; j++) {
      if (numPosTemp.some(function (element) {
         return numPos[j].includes(element);
      }) == true) {
      k++;
      }
   }

   // will only add into numPos if totally no match
   if (k == 0) {
      numPos.push(numPosTemp);
   }
}
console.log(numPos);

一个更有效的解决方案是生成一个包含 0 到 9 的 10 个数字的数组。然后您可以将这个数组打乱以使其随机化,然后将数组分成两部分:

function shuffle(array) {
  // From: https://stackoverflow.com/a/12646864/5648954
  for (var i = array.length - 1; i > 0; i--) {
    var j = Math.floor(Math.random() * (i + 1));
    var temp = array[i];
    array[i] = array[j];
    array[j] = temp;
  }
  return array;
}

function chunk(arr, n) {
  return arr.length ? [arr.slice(0, n), ...chunk(arr.slice(n), n)] : [];
}

const groups = 5; // 5 groups
const nums = Array.from({length: groups * 2}, (_, i) => i); // [0, 1, 2, ... 9]

const res = chunk(shuffle(nums), 2);
console.log(res);

如果您希望数字能够翻倍,您可以维护一组字符串。字符串表示内部数组的字符串版本[x, y] -> "x,y"对于您要创建的每个数字对,您可以检查数字的格式化字符串版本是否在集合中。与数组相比,使用集合具有高效的查找。如果格式化字符串出现在集合中,那么您可以生成随机数字,直到您的集合中没有两个数字为止。找到两个数字后,您可以将它们添加到您的集合中,并在最终结果中使用它们作为一对数字:

const groups = 5; // 5 groups
const seen = new Set();
const format = (...args) => args.join();
const nums = Array.from({length: groups}, () => {
  let x, y;
  do {
    x = Math.floor(Math.random() * groups*2); 
    y = Math.floor(Math.random() * groups*2);
  } while(x !== y && seen.has(format(x,y)));
  seen.add(format(x, y));
  return [x, y];
});

console.log(nums);

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章