此题为笔试题的读程序题。
题目程序代码如下:
#include
using namespace std;
int number,ndata,data[100],sum;
void solve(int s,int sign,int n){
int i;
for(i=s;i>number>>ndata;
sum=0;
for(i=0;i>data[i];
solve(0,1,1);
cout<
输入:1000 3 5 13 11
输出:
分析:此题是典型的for循环内插入递归调用,其实也可以转换成循环嵌套。在求解此题之前可以先缩小一下规模,寻找程序运行的方式。只要找到这个子问题的方式,那么这个题也就引刃而解了。
我们不如先把规模缩小。
#include
using namespace std;
int number,ndata,data[100],sum;
void solve(int s,int sign,int n){
int i;
for(i=s;i>number>>ndata;
sum=0;
for(i=0;i>data[i];
solve(0,1,1);
cout<
运行此程序的结果为:
1000 3 5 13 11
1.1000
1.800
1.815
2.815
2.815
1.615
2.615
2.615
1.1615
1.1539
2.1539
2.1539
1.2539
2.2539
2539
那么现在开始模拟这个程序的执行过程:
首先,s,sign和n的值从主函数中传到子函数solve中的初值为0,1,1。
那么第一次执行的值为:
solve(0,1,1);
for(i=0;i<3;i++)
sum=0+1*(1000/1)=1000;
然后调用函数,由递归式solve(i+1,-sign,n*data[i])知,此时变为solve(1,-1,1*data[0])=solve(1,-1,1*5)=solve(1,-1,5);
那么第二次执行的值为:
solve(1,-1,5);
for(i=1;i<3;i++)
sum=1000-1*(1000/5)=800;
继续调用函数,此时变为solve(2,1,5*data[1])=solve(2,1,5*13)=solve(2,1,65);
那么第三次执行的值为:
solve(2,1,65);
for(i=2;i<3;i++)
sum=800+1*(1000/65)=815;
继续调用函数,此时变为solve(3,-1,65);
但是,此时i=3,不符合循环条件,所以递归结束。开始返回。
返回:(P.S:学过的递归的oler应该都知道,递归是通过栈来实现,所以可得之前计算所产生的值都被压栈了。现在所要做的操作也就是弹栈。)
现在开始返回,由于最后一次有效递归是solve(2,1,65)。所以把最后一次递归所产生的值815带到上一层solve(1,-1,5)中。
此时执行的值为:
solve(1,-1,5);
for(i=1;i<3;i++)
sum=815-1*(1000/5)=615;
此时sum的值为615。
这一次返回有效(“有效”意为可以进行运算)。
继续返回,这一次返回到了递归”头“(solve(0,1,1))
此时执行的值为:
solve(0,1,1);
for(i=1;i<3;i++)
sum=1000+615=1615;
但现在还不能出来。还要重新进行新一轮递归。但运算方法与上面的一样。
此时执行的值为:
solve(1,-1,5);
for(i=2;i<3;i++)
sum=1615-1*(1000/13)=1539;
接下来i=3,不符合条件,再一次返回。
这次返回到开头(solve(0,1,1))
此时执行的值为:
solve(0,1,1);
for(i=2;i<3;i++)
sum=1000+1539=2539;
接下来i=3,不符合条件,再一次返回。可是这一次的位置已经是在开头,没有上层在继续返回,所以整个递归函数段结束。
然后就是输出2539了!
当然,原程序的运行原理也就是这样了(同理可得),至于答案是怎么算出来的,请读者自己去算一下。(不要怪我没说题目输出是328)