繁体   English   中英

有人可以解释一下此递归JS代码以计算指数吗?

[英]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 ^ 416 ,因此power(2, 4)将返回16 if()语句检查指数(幂)是否为零,如果为零,则返回1幂0的任何数字等于1。

最后一行

return base * power(base, exponent - 1);

是一个递归函数,可从其内部调用power() ,但是由exponent的值指定多次。


我将尝试从下至上或“从中间”来解释递归。 可能更容易理解。

最底部的power()调用将21作为其参数,并将返回1 然后,该返回值将在power()的第二次向上调用中使用,因此这次传递的参数是22 ,输出4 ,依此类推,直到对power()的最上面的调用传递了24 ,返回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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM