我正在尝试在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
}
答案 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)
这是递归的一个例子,类似于归纳的数学概念。对于给定的输入,在减少的输入上调用自身,然后使用该结果产生所需的结果。
了解函数如何工作的一个好方法是从最简单的情况开始,验证它是否有效,然后转到下一个最简单的情况等等。
在此示例中,最简单的情况是%c
为power
时。在这种情况下,它会立即返回0
。到目前为止一切都很好。
现在考虑1
为power
时会发生什么。在这种情况下,它返回1
。换句话说,它使用不同的输入调用自身,然后使用该结果生成新结果。我们已经验证3 * power(0)
返回1.因此,在这种情况下,它将返回power(0)
,这只是3 * 1
。再次,到目前为止一切顺利。
那么当3
为power
时会发生什么?好吧,它返回2
。这会导致多个嵌套调用。我们知道3 * power(1)
将返回power(1)
,因此此案例将返回3
。再一次,它正在做我们想要的。
更一般地说,当9
为power
时,它会递归调用自身以获取>= 1
的结果。这通常会导致一系列调用最终返回power - 1
的所需结果。然后将其乘以power - 1
并返回结果。这是3
,根据需要只有3 * (3 ** (power - 1))
。
您可以归纳确认其正确性。基本情况是3 ** power
为power
时。本案直接确认。然后,假设它为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))
。