2012-03-07 40 views
1

即使它是一个非常简单的例子,我无法理解这种递归。当它进入power(base, exponent - 1);那该怎么办?如果直到exponent等于0,电源才会被调用,事情会如何倍增?有人可以解释这个递归的JS代码来计算指数吗?

function power(base, exponent) { 
    if (exponent === 0) { 
     return 1; 
    } else { 
     return base * power(base, exponent - 1); 
    } 
} 
+2

Java不是JavaScript的。删除了java标签。 – 2012-03-07 23:12:53

+0

改变问题得到较小的情况下'功率(基地,指数 - 1)'和*使用*它与“解决”部分'base' - 在“*使用*”在这个例子只是乘法。 – miku 2012-03-07 23:12:59

+0

@AndrewWhitaker但它有相同的语法,所以我认为那里的人也会知道。 – 0x499602D2 2012-03-07 23:14:29

回答

5

让我们从头开始。

比方说,你叫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); 

至于非整数......除了抛出异常外,没有其他解决方法。将一个数字提高到非整数的能力是有道理的,所以你不想只截断指数或者假​​装他们没有尝试去做 - 你最终会返回错误的答案。

5

这类似于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

+0

啊,但哪里的最终结果从何而来。在我的印象中,功能会越来越调用,指数不断下降到零,因此函数应该返回1.但我只是不明白这其中32来自于'功率(2,5);' – 0x499602D2 2012-03-07 23:18:14

+0

数学应该帮助你用它http://en.wikipedia.org/wiki/Exponentiation – 2012-03-07 23:21:47

0

基= 10 功率= 3

10 *功率(10,2)

10 * 10 *功率(10,1)

10 * 10 * 10

对于正整数也许可以...

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。

2

假设初始呼叫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)的后续调用...

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) 
0

让我们尝试一些数学来解释这一点。

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; 
} 

从何而来,即东西向零功率始终等于1,基本情况:f(x,0) = 1

这就是这个递归是如何衍生的。

相关问题