javascript唯一随机数 [英] javascript unique random numbers
问题描述
专家
- 我希望在两个数字之间(从网页的文本框中)生成唯一的随机数.
- 我正在使用数组存储数字.当用户单击按钮时,它会给出第一个随机数,将其存储在数组中;当用户再次单击按钮时,它将生成随机数,将其与数组号进行比较;如果不同,则将其存储并显示.
- 如果显示最大可能的不同数字,则清除数组并通知用户.
- 我已经编写了代码,但是它给出了错误:堆栈溢出,或者有时我得到重复的结果.
任何人都可以阐明代码:
Can anyone shed a light on code:
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);
}
}
推荐答案
我看不到代码是如何产生堆栈溢出的(即使funShow
调用了funClick
并且funClick
调用了funShow
,funShow
对funClick
的调用永远不会由于逻辑错误而发生-修复该错误,虽然会出现堆栈溢出),但是它有几个问题.查看评论:
I fail to see how that code is generating a stack overflow (even though funShow
has a call to funClick
and funClick
has a call to funShow
, funShow
's call to funClick
should never happen because of a logic error -- fix the error and you'll get a stack overflow, though), but it has several issues. See the comments:
// 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);
}
}
有两种方法可以解决此问题.这基本上就是您要尝试执行的操作,但是没有递归:
There are two ways to approach this. Here's one that's basically what you were trying to do, but without recursion:
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(", ");
}
这样做的问题是,由于我们必须随机击中最后几个插槽,因此可能要花很长时间才能填满.
The problem with that is that it can take a long time to fill the last few slots, since we have to hit them randomly.
另一种方法是按顺序产生具有数字的数组,然后将其弄乱.对于大范围,它可以显着提高效率.像这样:
The other way is to produce the array with the numbers in order, then mess it up. It can be dramatically more efficient for large ranges. Something like this:
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(", ");
}
但是,仅随机执行一次nums.sort(...)
可能不会成功产生随机结果; 请参阅本文了解更多. (感谢电子商务的链接以及他在下面的输入.)
But, just doing the nums.sort(...)
randomly once may well not be as successful at producing random results; see this article for more. (Thanks to eBusiness for that link and for his input on the below.)
因此,您可能想走得更远,并进行进一步的随机操作.这是另一个示例:
So you may want to go further and throw in further random operations. Here's another example:
function funClick() {
var num1 = parseInt(document.getElementById('lnum').value, 10);
var num2 = parseInt(document.getElementById('hnum').value, 10);
var nums = [];
var n, x, y;
var num;
// 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 (n = num1; n <= num2; ++n) {
nums.push(n);
}
// We only need to shuffle it if it's more than one element long
if (nums.length > 1) {
// Sort it "randomly"
nums.sort(function(a, b) {
return 0.5 - Math.random();
});
// Throw a bunch of random swaps in there
for (n = 0; n < nums.length; ++n) {
do {
x = Math.floor(Math.random() * nums.length);
}
while (x === n);
num = nums[x];
nums[x] = nums[n];
nums[n] = num;
}
}
// Show the result
document.getElementById('rgen').innerText = nums.join(", ");
}
以数组排序为起点,但是在元素之间也进行了一系列随机交换.它仍然可以在恒定时间内运行,但是比单独使用数组排序要有更好的结果.自然,您将要测试发行版.
That does the array sort thing as a starting point, but then does a bunch of random swaps between elements as well. It still runs in constant time, but should have a better result than using the array sort alone. Naturally, you'll want to test the distribution.
这篇关于javascript唯一随机数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!