C中的递归函数将3乘以另一个数

时间:2016-02-19 13:49:15

标签: c

我正在尝试在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
}

5 个答案:

答案 0 :(得分:3)

是的,它在第一次通过时需要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()的第一行。

答案 1 :(得分:2)

这是递归的本质。

在数学意义上,你可以将3 ^ n的幂定义为3 * 3 ^(n - 1),对吗?毕竟3到任何东西都是3倍乘本身那么多次吧?

递归只是说答案是&#34;什么是权力3?&#34;那么它是3倍功率减去1倍。您只需要在power为0时处理大小写,并且返回的值将乘以递归调用的次数乘以3。

这是一个很好的学习练习,但你应该更喜欢pow(3,power),因为以这种方式计算会更有效率,并且你不会有超过最大递归调用堆栈的风险。

答案 2 :(得分:0)

考虑编写显示示例的每个入口和出口的命令流。另外,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;
}

答案 3 :(得分:0)

这是递归的一个例子,类似于归纳的数学概念。对于给定的输入,在减少的输入上调用自身,然后使用该结果产生所需的结果。

了解函数如何工作的一个好方法是从最简单的情况开始,验证它是否有效,然后转到下一个最简单的情况等等。

在此示例中,最简单的情况是%cpower时。在这种情况下,它会立即返回0。到目前为止一切都很好。

现在考虑1power时会发生什么。在这种情况下,它返回1。换句话说,它使用不同的输入调用自身,然后使用该结果生成新结果。我们已经验证3 * power(0)返回1.因此,在这种情况下,它将返回power(0),这只是3 * 1。再次,到目前为止一切顺利。

那么当3power时会发生什么?好吧,它返回2。这会导致多个嵌套调用。我们知道3 * power(1)将返回power(1),因此此案例将返回3。再一次,它正在做我们想要的。

更一般地说,当9power时,它会递归调用自身以获取>= 1的结果。这通常会导致一系列调用最终返回power - 1的所需结果。然后将其乘以power - 1并返回结果。这是3,根据需要只有3 * (3 ** (power - 1))

您可以归纳确认其正确性。基本情况是3 ** powerpower时。本案直接确认。然后,假设它为0提供了正确的结果,我们可以看到它还将从递归步骤为power - 1提供正确的结果。只有当结果变得足够大才能溢出时,它才会失败。

答案 4 :(得分:0)

我建议比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))