我正在CodeAcademy.com学习Javascript,我很难理解一个练习题,虽然我似乎找到了正确的答案。
该代码旨在帮助某人计算出当有人购买时他们应该回馈多少变化。它需要一个数字,并计算他们应该回馈多少个季度和多少便士。
这是我不明白的地方:
•第一次遇到第11行时,代码是否应该停止运行?如果没有,为什么不呢?
•如果代码在进入第11行时确实停止运行,为什么我能够在第10行之后放置代码并且它会在给出答案之前执行三次?我发现情况就是这样,所以它让我质疑我对代码如何工作的理解!我在第10行之后添加了行quarters += 1;
,它返回6。
var change = 0;
var quarters = 0;
function howManyQuarters(howMuchMoney) {
if (howMuchMoney < 0.25) {
change = howMuchMoney;
return 0;
}
else {
quarters += 1;
howManyQuarters(howMuchMoney-0.25);
return quarters; // << line 11
}
}
change = 0.99;
console.log ("Pay out " + howManyQuarters(change) + " quarters");
console.log ("And you'll have " + change * 100 + " pennies left over");
答案 0 :(得分:3)
代码在第11行上没有第一次停止运行,因为它第一次到达第10行时(有效地)返回到第3行。
尝试以这种方式拍照。我已经列出了递归的级别:
1. (Line 15) howManyQuarters(0.99)
2. (Line 4) howMuchMoney is > 0.25...so else applies
3. (Line 10) howManyQuarters(0.74) --> 0.74 = 0.99-0.25
4. (Line 4) howMuchMoney is > 0.25...so else applies
5. (Line 10) howManyQuarters(0.49) --> 0.49 = 0.74-0.25
6. (Line 4) howMuchMoney is > 0.25...so else applies
7. (Line 10) howManyQuarters(0.24) --> 0.24 = 0.49-0.25
8. (Line 4) howMuchMoney is < 0.25...so enter main body of if clause
9. (Line 6) return 0;
11. (Line 11) return quarters;
12. (Line 11) return quarters;
13. (Line 11) return quarters;
14. (Line 11) return quarters;
答案 1 :(得分:1)
不一定。使用递归,您可能会多次调用函数,并且每次调用都需要在代码完成函数执行之前返回。因此,如果howManyQuarters被调用3次,它将在函数调用之后立即执行代码(在这种情况下是返回语句),这也是很多次。
希望这很清楚。
答案 2 :(得分:1)
这是递归的全部要点:函数调用自身直到满足停止条件并变为true,然后它将不再调用自身。
在这种情况下,是的,函数确实会停在return quarters;
行,但此时它已经在行中调用了自己。
停止条件是确保你没有无限循环 - 当调用函数时,你给它一个数字 - 当这个数字小于0.25时,函数将停止。所以:
基本示例:
返回值本身由在函数外部声明的全局变量管理 - 每次函数调用自身时,它会将该变量递增1,因此最后您知道它被调用了多少次。现在你可以在this example中看到它并不是很聪明 - 第二次调用具有相同变化量的函数会带来错误的结果。
答案 3 :(得分:1)
功能正确。递归是计算机科学中一种神奇而强大的方法。递归函数总是具有相同的结构:
function myRecursive(nSizeData){
if(baseCondition is TRUE){
//compute the function with nSizeData
//do stuff here
}
else{
//call the same function with a smaller size set of data
//this condition ensure that the baseCondition will eventually be matched
myRecursive(mSizeData);
}
}
有一个基本条件代表函数的基础:如果函数输入数据与baseCondition匹配,函数可以在不调用自身的情况下进行计算。否则,它会调用自己传递较小的数据集。递归函数的计算过程可以通过堆栈表示:每次调用函数时我都会进入堆栈,当函数返回一个值时,我会弹出堆栈。第一个pop将始终是baseCondition块的结果。
警告:如果baseCondition永远不匹配,最终将发生堆栈溢出。
一个典型的例子是整数的阶乘函数:
function factorial(n){
if(n==0 || n==1){
return 1;
}
else{
return factorial(n-1);
}
}
有关详细信息,请参阅here。
答案 4 :(得分:0)
每次输入该功能时,最终都必须通过return
退出。这是一个图表:
Enter howManyQuarters.
Enter howManyQuarters.
Enter howManyQuarters.
Enter howManyQuarters.
return
return
return
return
答案 5 :(得分:0)
对不起,有点offtopic,但为什么你需要这么简单的数学工作这么复杂的功能?这实际上是一行函数需要(但是汇总结果)。
function howMuchMoney(val) {
return [
Math.floor(val / 0.25),
parseFloat((val % 0.25).toFixed(2))
];
}
就是这么简单。
答案 6 :(得分:0)
这里我能想到的是
return quarters;
在第10行之后没有执行语句。 当控件遇到
时howManyQuarters(howMuchMoney-0.25);
语句它自己调用而不执行第11行。 完成所有递归后,控件从每个循环(递归)中出来并执行第11行。