簡體   English   中英

C中的遞歸函數將3乘以另一個數的冪

[英]Recursive function in C to take 3 to the power of another number

我正在嘗試在C中編寫一個遞歸函數,將3的值取為另一個數的冪。 例如,如果我輸入4,程序將返回值81.以下代碼是問題的答案。 但我無法清楚地了解代碼如何解決問題。 我的意思是當4傳遞給函數時,函數體中的前3行將被忽略,直接跳到“// This line”。 然后如何從那里程序返回數字81.該函數再次調用自己3傳遞? 3 * three_power(3)? 我無法清楚地理解這一點。 誰能解釋一下? 抱歉,因為這是一個愚蠢的問題,我是C的新手。

#include <stdio.h>
int three_power(int power);
int main(){
    int a=4;
    int b=9;
    printf("\n3 to the power of %d is %d", a, three_power(a));
    printf("\n3 to the power of %d is %d", b, three_power(b));
    return 0;
}
int three_power(int power){
    if (power < 1){
        return( 1 );
    } else
    return (3* three_power(power-1));  //This line
}

是的,它需要在else通過第一種方式,這導致了遞歸調用分支4 - 1再次采取else分支,等下到基本情況時power為0,僅返回1 (因為3 0 1)。

完整的鏈條是

3 * three_power(3) =
3 * (3 * three_power(2)) =
3 * (3 * (3 * three_power(1)) =
3 * (3 * (3 * (3 * three_power(0))) =
3 * (3 * (3 * (3 * (1)))) =
3 * 3 * 3 * 3 = 81

很難想象,但就是這樣。

您當然可以在調試器中單步執行此操作以獲得感覺,或者只需添加printf("power=%d\\n", power); three_power()的第一行。

這是遞歸的本質。

在數學意義上,你可以將3 ^ n的冪定義為3 * 3 ^(n - 1),對嗎? 畢竟3到任何東西都是3倍乘本身那么多次吧?

遞歸只是簡單地說“對權力是什么?”的答案。 那么它是3倍功率減去1倍。 您只需要在power為0時處理大小寫,並且返回的值將乘以遞歸調用的次數乘以3。

這是一個很好的學習練習,但是您應該更喜歡pow(3,power),因為以這種方式計算更有效,並且您沒有超過最大遞歸調用堆棧的風險。

考慮編寫顯示示例的每個入口和出口的命令流。 另外,else上的返回值是單行。 我將重寫它顯示正確的括號。

1E。 輸入值為4

2E。 輸入值3

3E。 輸入值為2

4E。 輸入值1

5E。 輸入值為0

5R。 返回1

4R。 返回3 * 5r = 3 * 1 = 3

3R。 返回3 * 4r = 3 * 3 = 9

2R。 retrun 3 * 3r = 3 * 9 = 27

1R。 返回3 * 2r = 3 * 27 = 81

int three_power(int power)
{
    if (power < 1)
    {
        return( 1 );
    }
    else
    {
        return (3* three_power(power-1));  //This line
    }
}

另一種單一回報的方法是

int three_power(int power)
{
    int rtnval;
    if (power < 1)
    {
        rtnval = 1;
    }
    else
    {
        rtnval = 3* three_power(power-1);  //This line
    }
    return rtnval;
}

這是遞歸的一個例子,類似於歸納的數學概念。 對於給定的輸入,在減少的輸入上調用自身,然后使用該結果產生所需的結果。

理解函數如何工作的一個好方法是從最簡單的情況開始,驗證它是否有效,然后繼續下一個最簡單的情況,等等。

在這個例子中,最簡單的情況是當power0 在這種情況下,它立即返回1 到現在為止還挺好。

現在考慮當power1時會發生什么。 在這種情況下,它返回3 * power(0) 換句話說,它使用不同的輸入調用自身,然后使用該結果生成新結果。 我們已經驗證power(0)返回1.所以在這種情況下,它將返回3 * 1 ,這只是3 再次,到目前為止一切順利。

那么當power2時會發生什么? 好吧,它返回3 * power(1) 這會導致多個嵌套調用。 我們知道power(1)將返回3 ,所以這種情況將返回9 再一次,它正在做我們想要的。

更一般地,當power >= 1 ,它遞歸地調用自身以獲得power - 1的結果power - 1 這通常會導致一系列調用最終返回所需的power - 1結果power - 1 然后將它乘以3並返回結果。 這是3 * (3 ** (power - 1)) ,根據需要只有3 ** power

您可以歸納地確認其正確性。 基本情況是power0 本案直接確認。 然后,假設它給出了power - 1的正確結果,我們可以看到它也將從遞歸步驟給出正確的power結果。 只有當結果變得足夠大才能溢出時,它才會失敗。

我建議比f(n)=3*f(n-1)更有效的遞歸。

這將是

// f(n) = 1 if n = 0
// f(n) = f(n/2)^2` if n is even
// f(n) = 3*f(n/2)^2 if n is odd

int power3(int n)
{
    int m;
    if (n == 0)
        return 1;
    else if (n % 2 == 0)
    {
        m = power3(n/2);
        return m*m;
    }
    else
    {
        m = power3(n/2);
        return 3*m*m;
    }
}

這樣,時間復雜度從O(n)減少到O(log(n))

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM