我过去曾尝试过询问与此问题相关的建议,并且我被告知问题的根源是“尾递归”。人们指示我切向相关的帖子,但我在将这些帖子中的建议应用到我的代码时遇到了麻烦。
有人可以解释一下我可以对我的代码进行的具体修改,以解决我遇到的递归问题(详见下文)?我花了好几个小时试图解决这个问题并且无处可去(noob here ...)。
所以,我的代码的一些背景:
这会在2到20之间生成2个不同的随机数:
function GenerateRandomNumber1to20No1() {
var min = 2, max = 20;
var random = Math.floor(Math.random() * (max - min + 1)) + min;
return random;
}
var GenerateRandomNumber1to20No1 = GenerateRandomNumber1to20No1();
$('.GenerateRandomNumber1to20No1').html(GenerateRandomNumber1to20No1);
function GenerateRandomNumber1to20No2() {
var min = 2, max = 20;
var random = Math.floor(Math.random() * (max - min + 1)) + min;
return (random !== GenerateRandomNumber1to20No1) ? random: GenerateRandomNumber1to20No2();
///////////HERE'S ONE PLACE WHERE RECURSION IS AN ISSUE, I BELIEVE //////////////
}
var GenerateRandomNumber1to20No2 = GenerateRandomNumber1to20No2();
$('.GenerateRandomNumber1to20No2').html(GenerateRandomNumber1to20No2);
这会生成2个不同于前2个数字的数字:
function GenerateRandomNumber1to20lessthanNo1() {
var min = 2, max = GenerateRandomNumber1to20No1-1;
var random = Math.floor(Math.random() * (max - min + 1)) + 1;
return random;
}
var GenerateRandomNumber1to20lessthanNo1= GenerateRandomNumber1to20lessthanNo1();
$('.GenerateRandomNumber1to20lessthanNo1').html(GenerateRandomNumber1to20lessthanNo1);
function GenerateRandomNumber1to20lessthanNo2() {
var min = 2, max = (GenerateRandomNumber1to20No2 - 1);
var random = Math.floor(Math.random() * (max - min + 1)) + min;
return (random !== GenerateRandomNumber1to20lessthanNo1) ? random: GenerateRandomNumber1to20lessthanNo2();
}
///////////HERE'S ANOTHER PLACE WHERE RECURSION IS AN ISSUE, I BELIEVE //////////////
var GenerateRandomNumber1to20lessthanNo2 = GenerateRandomNumber1to20lessthanNo2();
$('.GenerateRandomNumber1to20lessthanNo2').html(GenerateRandomNumber1to20lessthanNo2);
我使用这些变量来替换具有与其各自变量对应的类的元素。
<span class = "GenerateRandomNumber1to20nNo2"></span>
<span class = "GenerateRandomNumber1to20nNo2"></span>
<span class = "GenerateRandomNumber1to20lessthanNo1"></span>
<span class = "GenerateRandomNumber1to20lessthanNo2"></span>
例如,<span class = "GenerateRandomNumber1to20nNo2"></span>
被替换为为变量GenerateRandomNumber1to20nNo2
生成的数字。
有时代码工作正常:变量生成,元素被这些变量替换。其他时候,变量不会填充,我得到一个如下所示的错误:
Uncaught RangeError: Maximum call stack size exceeded
at GenerateRandomNumber1to20lessthanNo2
我被告知我收到此错误,因为我使用“尾递归”但我在将“尾递归”的研究应用于我的代码时遇到了麻烦。我在代码中指出了我认为递归是个问题的地方。
如果有人可以使用我的特定代码给我建议,我将非常感激。
function GenerateRandomNumber1to20lessthanNo2() {
var min = 2, max = (GenerateRandomNumber1to20No2 - 1);
var random = Math.floor(Math.random() * (max - min + 1)) + min;
return (random !== GenerateRandomNumber1to20lessthanNo1)// <=== HERE
? random
: GenerateRandomNumber1to20lessthanNo2();
}
想象一下你得到两个随机数的情况:2和3.现在,你试图滚动小于2和3的随机数,同时仍然使用2作为最低数字。
由于以下几个原因,你迷失在这些功能中:
我将使用示例重构更新此内容。
function randomBetween (min, max) {
var ceiling = max + 1;
return Math.floor(Math.random() * (ceiling - min)) + min;
}
function randomBetweenAndExcluding (min, max, excluding) {
var random;
do {
random = randomBetween(min, max);
} while(random === excluding);
return random;
}
var random1High = randomBetween(2, 20);
var random1Low = randomBetween(1, random1High - 1);
var random2High = randomBetweenAndExcluding(2, 20, random1High);
var random2Low = randomBetweenAndExcluding(1, random2High - 1, random1Low);
function addText (selector, text) {
const el = document.querySelector(selector);
if (el) { el.textContent = text; }
}
addText(".GenerateRandomNumber1to20nNo1", random1High);
addText(".GenerateRandomNumber1to20nNo2", random2High);
addText(".GenerateRandomNumber1to20lessthanNo1", random1Low);
addText(".GenerateRandomNumber1to20lessthanNo2", random2Low);
// PS you have a copy-paste error in your HTML classes, too
// the names are too long, and too similar, and already confused
// because of the overwriting functions with vars
在这个代码的情况下,random1High
和random2Low
完全可以接受相同的数字。如果这是不可接受的,如果滚动的数字是2, 1, 3
,你将打开另一个无限循环的将死。如果这是不可接受的,那么你需要在3到20之间随机运行前两个数字,因此底部仍然有1和2的空间,并使排除功能更加有趣。
希望在这里看到移动的部件更容易。
如果你想像以前一样继续使用递归(一个函数调用自身,从内部),你可以定义第二个函数
function randomBetweenAndExcluding (min, max, exclude) {
var random = randomBetween(min, max);
return random === exclude
? randomBetweenAndExcluding(min, max, exclude)
: random;
}
我通常更喜欢递归。递归的一个缺点是,如果在返回之前在太多函数内调用太多函数,通常会在数十到数百之间的某个地方,在有效代码中“打击堆栈”/命中“堆栈溢出”(同样的事情)是可能的。成千上万的电话,没有返回,但仍然)。因此,在无限递归的情况下,最终浏览器会抛出错误。无限的while
循环的缺点是你的浏览器和页面锁定,循环永远不会停止运行,最终,也许,你的浏览器会弹出一些东西并说“哎;这肯定已经运行了很长时间;它看起来就像页面死了,你想要杀死它吗?“