2012-03-07 61 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

這就是這個遞歸是如何衍生的。

相關問題