javascript独特的随机数

时间:2013-01-12 08:09:27

标签: javascript random stack-overflow

专家

  • 我希望在两个数字之间生成唯一的随机数(来自网页的文本框)。
  • 我使用数组存储数字。当用户单击按钮时,它会给出第一个随机数,将其存储在数组中,当用户再次单击按钮时,它会生成随机数,将其与数组编号进行比较,如果不同,则将其存储并显示。
  • 如果显示最大可能的不同数字,则清除数组并通知用户。
  • 我编写了代码,但它给出了错误:堆栈溢出,或者有时会显示重复的结果。

任何人都可以了解代码:

var allnums = new Array();
var num1= new Number;
var num2= new Number;

function funClick()
{
  var num1 = Number(document.getElementById('lnum').value); 
  var num2 = Number(document.getElementById('hnum').value); 

  if (allnums.length==num2)
  {
    alert("Maximum non-duplicate numbers served. Now resetting the counter.");
    allnums = [];
    return;
  }

  if (num1<num2) 
  {
    x = Math.floor(Math.random() * (num2 - num1 + 1)) + num1;
    funShow(x);
  }
  else
  {
    alert("You entered wrong number criteria!");  
  }
}

function funShow(x)
{
  var bolFound = false;
  for (var i=0;i<allnums.length;i++)
  {
    if((allnums[i])==x)
    {   
      funClick();
    }    
  }
  if (bolFound == false)
  {
    document.getElementById('rgen').innerText  = x;
    allnums.push(x);
  }
}

3 个答案:

答案 0 :(得分:2)

我无法看到该代码如何生成堆栈溢出(即使funShow调用了funClick并且funClick调用了funShow,{{ 1}}对funShow的调用永远不应该因为逻辑错误而发生 - 修复错误并且你会得到堆栈溢出,但是它有几个问题。见评论:

funClick

有两种方法可以解决这个问题。这是一个基本上你想要做的,但没有递归:

// style: Use [], not new Array()
var allnums = new Array();

// `new Number` doesn't do anything useful here
var num1 = new Number;
var num2 = new Number;

function funClick() {
    // For user-entered values, use parseInt(value, 10) to parse them into numbers
    var num1 = Number(document.getElementById('lnum').value);
    var num2 = Number(document.getElementById('hnum').value);

    if (allnums.length == num2) {
        alert("Maximum non-duplicate numbers served. Now resetting the counter.");
        allnums = [];
        return;
    }

    // & is a bitwise AND operation, not a logical one. If your goal is to see
    // if both numbers are !0, though, it works but is obtuse.
    // Also, there is no ltnum2 variable anywhere, so trying to read its value
    // like this should be throwing a ReferenceError.
    if (num1 & ltnum2) {
        // You're falling prey to The Horror of Implicit Globals, x has not
        // been declared.
        x = Math.floor(Math.random() * (num2 - num1 + 1)) + num1;
        funShow(x);
    } else {
        alert("You entered wrong number criteria!");
    }
}

function funShow(x) {
    var bolFound = false;
    // Again, & is a bitwise AND operation. This loop will never run, because
    // you start with 0 and 0 & anything = 0
    // But it should be throwing a ReferenceError, as there is no ltallnums
    // anywhere.
    for (var i = 0; i & ltallnums.length; i++) {
        if ((allnums[i]) == x) {
            funClick();
        }
    }
    // This condition will always be true, as you've done nothing to change
    // bolFound since you set it to false
    if (bolFound == false) {
        document.getElementById('rgen').innerText = x;
        allnums.push(x);
    }
}

Live Example | Source

问题在于填充最后几个插槽需要很长时间,因为我们必须随机点击它们。

另一种方法是按顺序生成带有数字的数组,然后搞砸它。对于大范围,它可以显着提高效率。像这样:

function funClick() {
    var num1 = parseInt(document.getElementById('lnum').value, 10);
    var num2 = parseInt(document.getElementById('hnum').value, 10);
    var nums = [];
    var targetCount;
    var x;

    // Check the inputs
    if (isNaN(num1) || isNaN(num2) || num2 <= num1) {
        alert("Please ensure that hnum is higher than lnum and both are really numbers.");
        return;
    }

    // Find out how many integers there are in the range num1..num2 inclusive
    targetCount = num2 - num1 + 1;

    // Produce that many random numbers
    while (nums.length < targetCount) {
        x = Math.floor(Math.random() * (num2 - num1 + 1)) + num1;
        if (nums.indexOf(x) < 0) {
            nums.push(x);
        }
    }

    // Show the result
    document.getElementById('rgen').innerText = nums.join(", ");
}

Live Example | Source

但是,只是随机地执行function funClick() { var num1 = parseInt(document.getElementById('lnum').value, 10); var num2 = parseInt(document.getElementById('hnum').value, 10); var nums = []; var x; // Check the inputs if (isNaN(num1) || isNaN(num2) || num2 <= num1) { alert("Please ensure that hnum is higher than lnum and both are really numbers."); return; } // Create an array with those numbers in order for (x = num1; x <= num2; ++x) { nums.push(x); } // Sort it with a random comparison function nums.sort(function(a, b) { return 0.5 - Math.random(); }); // Show the result document.getElementById('rgen').innerText = nums.join(", "); } 一次可能不会产生随机结果; see this article for more(感谢eBusiness关于该链接以及他在下面的输入。)

所以你可能想要进一步推进进一步的随机操作。这是另一个例子:

nums.sort(...)

Live Example | Source

将数组排序作为起点,但随后在元素之间进行了一系列随机交换。它仍然在恒定的时间运行,但应该比单独使用数组排序有更好的结果。当然,您需要测试分发。

答案 1 :(得分:2)

使用数组:

var uniqueRandomNumbers = new Array();
var totalNumbers = 100;
for (var i=0; i<totalNumbers; i++){
    uniqueRandomNumbers.push(i);
}
uniqueRandomNumbers.sort(function() {return 0.5 - Math.random();});
var uniqueNumber;
for(var i=0; i<uniqueRandomNumbers.length; i++){
    uniqueNumber = uniqueRandomNumbers[i];
    //do something with the number
}

答案 2 :(得分:0)

由于我无法编辑Crowder的答案,这里是一种简单无偏的加扰数组的方式:

function scramble(nums){
    for (var n = nums.length; n; n--) {
        var x = Math.floor(Math.random() * n);
        var num = nums[n-1];
        nums[n-1] = nums[x];
        nums[x] = num;
    }
}