【问题标题】:JS create an array with unique random numbersJS 创建一个具有唯一随机数的数组
【发布时间】:2019-01-06 19:56:32
【问题描述】:

完整代码如下所示,理想情况下,我们有 4 个 div 框需要随机填充随机数 ansValue,其中一个(rightAnsValue 及其 rightAnsId)已经完成并且工作正常,我已经设法使其独一无二与其他人相比(没有注释部分的代码)。但是遇到了使其他人独一无二的问题,我的盒子里一直有一些相同的值。在 cmets 中是我试图解决这个问题的一种方法,但可以肯定的是,有一个更简单、更智能的解决方案实际上可以工作。如果您能帮助找到一个可以理解的解决方案来解决这个问题,我将不胜感激。 (P.S. 我也看到过类似的问题,但是它们要么太难,要么没有 JS。)

function createAnswers(){
    for(ansId=1; ansId<5; ansId++){
        if(ansId!=rightAnsId){
            for(i=1; i<10; i++){
                digitArray[i-1] = i;
            }
            genNewRandNum();

            // ansArray.length = 3;
            // ansArray.push(ansValue);
            // for(k=0; k<3; k++){
            //     if(ansArray[k] == ansArray[k+1] || ansArray[k] == ansArray[k+2]){
            //         genNewRandNum();
            //         ansArray[k] = ansValue;
            //     }else if(ansArray[k+1] == ansArray[k+2]){
            //         genNewRandNum();
            //         ansArray[k+1] = ansValue;
            //     }else{
            //         break;
            //     }
            // }

            if(ansValue!=rightAnsValue){
                document.getElementById("box" + ansId).innerHTML = ansValue;
            }else{
                genNewRandNum();
                document.getElementById("box" + ansId).innerHTML = ansValue;
            }
        }
    }
}

我生成新数字的方式:

function genNewRandNum(){
    rand1 = digitArray[Math.floor(Math.random() * digitArray.length)];
    rand2 = digitArray[Math.floor(Math.random() * digitArray.length)];
    ansValue = rand1 * rand2;
}

【问题讨论】:

  • 所以你有四个盒子,你想在每个盒子里输出一个 1 到 9 之间的唯一随机数。这就是你要找的吗?
  • 我猜,其中一个是问题的正确答案。 UPD:它应该是一个盒子中的 ansValue,它是一个随机数,它本身是在 genNewRandNum() 函数中完成的
  • 您似乎在显示两个随机数的乘积?我认为我们需要更多的上下文? rand1rand2 在哪里使用?它们是否显示在某个地方?展示这些产品的目的是什么?是猜谜游戏吗?需要猜什么?
  • 从这段代码中我无法确定正确的答案值是什么。但是,如果您知道正确答案,那么您可以更新我的答案中的代码以将正确答案传递给它,然后只返回正确答案以外的值。现在您将拥有一个由 3 个随机唯一值加上 1 个正确答案组成的数组.您可以将这 4 个值随机打乱到 1 个数组中并将其分配给框
  • 之所以在外部函数中统计ansValue,是为了让代码更容易阅读。我创建了一个随机问题,例如:“5x9?”,使用了 1 到 9 之间的数字(我用这些数字制作 ansValue 的原因)。有 3 个带有随机答案的框(ansValue),第 4 个是正确的(具有正确的AnsValue)。我的问题是让它们都不同。对不起,如果让任何人感到困惑。

标签: javascript arrays unique


【解决方案1】:

将您的 genNewRandNum() 替换为以下代码。我已经使用 IIFE 创建了一个闭包变量 alreadyGeneratedNumbers,它在返回的函数 generateRandomNumber() 中可用。

所以每次执行 genNewRandNum() 时,它都会检查 alreadyGeneratedNumbers 以确保它始终返回 1 到 9 之间的唯一值。

var genNewRandNum = (function(){
  var alreadyGeneratedNumbers = {};
  return function generateRandomNumber() {
    var min = Math.ceil(1),
      max = Math.floor(9);
      randomNumber = Math.floor(Math.random() * (max - min + 1)) + min;
    
    if(alreadyGeneratedNumbers[randomNumber]) {
      return generateRandomNumber();
    } else {
      alreadyGeneratedNumbers[randomNumber] = randomNumber;
      return randomNumber;
    }

  }
})();



console.log(genNewRandNum());
console.log(genNewRandNum());
console.log(genNewRandNum());
console.log(genNewRandNum());
console.log(genNewRandNum());
console.log(genNewRandNum());
console.log(genNewRandNum());
console.log(genNewRandNum());
console.log(genNewRandNum());

注意:如果你第 10 次调用 genNewRandNum() 会抛出错误。因此,如果您有一个用例,在返回 1 到 9 的所有数字后需要重置它,那么您需要添加代码来处理它

【讨论】:

  • 不完全是我想要的,因为我很擅长提问,但感谢您的建议,我想我可以重新设计这个以适应)
【解决方案2】:

暴力破解的最简单方法是使用接受/拒绝采样。你可以这样做:

uniqueRandomNumbers = function(n, nextRandom)
{
  var nums = {}; var m = 0;

  while(m < n)
  {
    var r = nextRandom();

    if(! nums.hasOwnProperty(r))
    {
      nums[r] = true; m++;
    }
  }

  return Object.keys(nums);
}

在这里,我使用 js 对象实现为哈希图的事实来获取哈希集。 (这有将数字转换为字符串的缺点,但如果您不打算立即对它们进行算术运算,这不是问题。)

为了获得 0 到 9 之间的四个唯一整数,您可以执行以下操作:

uniqueRandomNumbers(4, function() { return Math.floor(Math.random() * 10); })

如果您想要一些比蛮力更好的东西(这可能与您的用例无关,但可以帮助某人在谷歌上搜索),一种选择是遍历每个元素并以适当的概率取走或留下它. this question 的答案中概述了这种方法。

【讨论】:

    猜你喜欢
    • 2012-04-29
    • 1970-01-01
    • 1970-01-01
    • 2022-09-23
    • 2013-01-27
    • 1970-01-01
    • 2021-01-12
    • 2021-06-18
    • 1970-01-01
    相关资源
    最近更新 更多