[英]Can someone please explain this recursive JS code to calculate exponents?
即使是一个非常简单的示例,我也无法理解它。 上power(base, exponent - 1);
那应该怎么办? 当幂不断被调用直到exponent
等于0时,事物如何相乘?
function power(base, exponent) {
if (exponent === 0) {
return 1;
} else {
return base * power(base, exponent - 1);
}
}
这类似于Math.pow()
; 它将base
参数提升为exponent
参数。
例如2 ^ 4
是16
,因此power(2, 4)
将返回16
。 if()
语句检查指数(幂)是否为零,如果为零,则返回1
幂0的任何数字等于1。
最后一行
return base * power(base, exponent - 1);
是一个递归函数,可从其内部调用power()
,但是由exponent
的值指定多次。
我将尝试从下至上或“从中间”来解释递归。 可能更容易理解。
最底部的power()
调用将2
和1
作为其参数,并将返回1
。 然后,该返回值将在power()
的第二次向上调用中使用,因此这次传递的参数是2
和2
,输出4
,依此类推,直到对power()
的最上面的调用传递了2
和4
,返回16
。
让我们从头开始。
假设您调用power(base, 0)
。 由于exponent
为0,因此该函数返回1。
现在,假设您调用power(base, 1)
。 由于这次exponent
不为0,因此该函数调用power(base, exponent - 1)
并将其乘以 base
。 (这是这里的关键...它从递归调用中获取结果,并加上自己的扭曲。)由于exponent - 1
= 0,并且power(base, 0)
为1,所以结果实际上是base * 1
。 阅读: base
。
现在启动power(base, 2)
。 最终是base * power(base, 1)
。 并且power(base, 1)
是base * power(base, 0)
。 最终结果: base * (base * 1)
。 读取: base
平方。
等等。
顺便说一句,如果情况不太明显,则此函数仅适用于非负整数指数。 如果exponent
为负,或什至是最小数大于或小于整数,则该函数将“永远”运行。 (实际上,一旦递归吞噬了所有堆栈,您很有可能导致堆栈溢出。)
您可以使用一些代码将功能修复为负功率
if (exponent < 0) return 1 / power(base, -exponent);
至于非整数类……除了抛出异常外,没有什么好办法解决这个问题。 将数字提高为非整数幂是有道理的,因此,您不想截短指数或假装他们没有尝试这样做-您最终会返回错误的答案。
假设初始呼叫为power(10, 3)
...
v-----first power() call returns base * (result of next power() call)
v-----second power() call returns base * (result of next power() call)
v-----third power() call returns base * (result of last power() call)
v------result of last power() call returns 1
(10 * (10 * (10 * (1))))
^-----return 1
^-----return base * 1 (10)
^-----return base * 10 (100)
^-----return base * 100 (1000)
或在左下方,在右上方。 每行都是对power()
的后续调用,从power(10, 3)
power()
开始...
return base * power(base, 2); // return base * 100 (1000)
return base * power(base, 1); // return base * 10 (100)
return base * power(base, 0); // return base * 1 (10)
return 1; // return 1 (1)
以2 ^ 3为例:
power(2, 3);
致电:
function power(2, 3) {
if (3 === 0) {
return 1;
} else {
return 2 * power(2, 2); //called
}
}
这导致:
function power(2, 2) {
if (2 === 0) {
return 1;
} else {
return 2 * power(2, 1); //called
}
}
这导致:
function power(2, 1) {
if (1 === 0) {
return 1;
} else {
return 2 * power(2, 0); //called
}
}
这导致:
function power(2, 0) {
if (1 === 0) {
return 1; //returned
} else {
return 2 * power(2, -1);
}
}
这导致:
function power(2, 1) {
if (1 === 0) {
return 1;
} else {
return 2 * 1; //returned
}
}
这导致:
function power(2, 2) {
if (2 === 0) {
return 1;
} else {
return 2 * 2; //returned
}
}
这导致:
function power(2, 3) {
if (3 === 0) {
return 1;
} else {
return 2 * 4; //returned
}
}
最终返回8,即2 ^ 3。
基本= 10力量= 3
10 *功率(10,2)
10 * 10 *功率(10,1)
10 * 10 * 10
对于正整数也许还可以...
让我们尝试用一些数学解释一下。
f(x,y) = x^y # (1) function definition
= x * x * x * ... * x # (2) multiply x with itself y times
= x * (x * x * ... * x) # (3) rewrite using parentheses for clarity
= x * (x^(y-1)) # (4) replace the second part by (1) notation
= x * f(x, y-1) # (5) replace again by using f(x,y) notation according to (1)
f(x,0) = 1 # base case: x^0 = 1
之后,您可以看到f(x,y) = x * f(x, y-1)
。
您也可以看到
if (exponent === 0) {
return 1;
}
源自,即一个基本情况,等于0的幂总是等于1: f(x,0) = 1
。
这就是这种递归的来源。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.