现在我正在通过Codecademy的递归轨道,我很困惑如何解释这个正确的代码。
// Create an empty array called "stack"
var stack = []
// Here is our recursive function
function power(base, exponent) {
// Base case
if ( exponent === 0 ) {
return 1;
}
// Recursive case
else {
stack[exponent-1] = base * power(base, exponent - 1); //confused by start of this line
return stack[exponent-1];
}
}
power(3,3)
console.log(stack) // [3,9,27]
如果exponent-1变为2然后是1然后是0,为什么3成为数组中第0位的元素而不是第2位(依此类推)?
我真的很感激任何帮助。
答案 0 :(得分:2)
在第一遍中,指数为3,因此您将在堆栈[2]处存储一个值。但是,在递归调用完成功率(3,2)...功率(3,1)之前,不会计算该值。
所以堆栈[3-1]的赋值前面有一个堆栈[3-2],后面依旧是堆栈[3-2]
答案 1 :(得分:2)
请注意,在执行此调用时有四个不同的指数,在power
调用的每个范围内都有一个。
call power(3, 3)
exponent' = 3
is not 0
calls power(3, 2)
exponent'' = 2
is not 0
calls power(3, 1)
exponent''' = 1
is not 0
calls power(3, 0)
exponent'''' = 0
is 0
returns 1
multiplies the return value by 3
assigns it to stack[exponent'''-1]: stack[0] = 3
returns 3
multiplies the return value by 3
assigns it to stack[exponent''-1]: stack[1] = 9
returns 9
multiplies the return value by 3
asigns it to stack[exponent'-1]: stack[2] = 27
returns 27
logs the value of stack
实际上,在从递归调用返回之后,堆栈是“向后”构建的,而不是在进入它们之前。如果您希望更好地表示调用堆栈,可以尝试添加
callstack.push(exponent);
在函数体的第一行。执行完脚本后,callstack
看起来就像您预期的那样[3, 2, 1, 0]
。
答案 2 :(得分:0)
如果你把它写在表格中会有所帮助:
power(3, 3) stack[2] = 3 * power(3, 2)
power(3, 2) stack[1] = 3 * power(3, 1)
power(3, 1) stack[0] = 3 * power(3, 0)
power(3, 0) return 1
然后替换值:
stack[0] = 3 * 1
stack[1] = 3 * 3
stack[2] = 3 * 9