近日一道猴子吃桃子的编程题:
猴子第一天摘下N个桃子,当时就吃了一半,还不过瘾,就又多吃了一个。第二天又将剩下的桃子吃掉一半,又多吃了一个。以后每天都吃前一天剩下的一半零一个。到第10天在想吃的时候就剩一个桃子了,问第一天共摘下来多少个桃子?
他需要打印每天吃完后剩下的桃子数,并要求不在主函数中打印。
显然,在主函数里加个for循环就结束了,但在递归函数里也是用for循环吗?
我们来考虑一下:
递归函数的基线条件应该是第10天为1,一般条件应该是
ok,我们考虑一下for循环打印语句:
#include <stdio.h>
//函数功能: 用递归法计算桃子个数
/* 入口参数:n表示第几天
返回值:桃子个数*/
int Peach(int n)
{
int m,i;
if (n==10)
return 1;
else
{
m=(Peach(n+1)+1)*2; //计算公式
for (i=10;i>=1;i--)
{
printf("第%d天还剩%d桃子\n",i,m);//打印语句
}
return m;
}
}
int main (void)
{
int x;
x=Peach(1);
printf("第一天有%d桃子\n",x);
return 0;
}
运行结果:
寄了。。。
运行结果解释:
注意到这样的话,比如说你想算Peach(8),他先算m,而m中包含Peach(9),于是让n=9,再来一遍Peach()函数,(注意,这时Peach(8)中的for循环还没开始打印!!!)
这时他算n=9的m,要用Peach(10)=1,成功算出了m,然后打印了for循环,注意这时m=Peach(9),然后开始从i=10打印到i=1的Peach(9)个桃子。接着把m返回给Peach(8)里面的Peach(9),算出Peach(8)里的m,再打印一遍Peach(8)个桃子,因此是这样的运行结果。
注意到变量的作用域问题,每次函数里的m都是开辟了一块新的内存,所以每次函数运行的m,都不是一个m。
所以我们发现,递归函数每次打印在再次调用自身时,自动类似于给自己加了一个for循环
看如下正确代码:
#include <stdio.h>
//函数功能: 用递归法计算桃子个数
/* 入口参数:n表示第几天
返回值:桃子个数*/
int Peach(int n)
{
int m;
if (n==10)
return 1;
else
{
m=(Peach(n+1)+1)*2; //计算公式
printf("第%d天还剩%d桃子\n",n,m);//打印语句
return m;
}
}
int main (void)
{
int x;
x=Peach(1);
printf("第一天有%d桃子\n",x);
return 0;
}
运行结果:
这样就成功了。