用递归代码实现斐波那契数列求解,利用转换规则(不简化) 将递归代码转换为非递归代码。(C++)
这次作业记得是五一时候做的,当时快放假时布置的,想了很久也没想出来怎么转化。
五一时做火车出去玩,还是在火车上突然就有了灵感,就写出来了。
不过,到现在时间已经有点长了,所以也记得不太清楚了,就简单的根据当时的作业报告,简单写一下吧。
转换规则如下:
(1) 设置一个栈(不妨用S表示),并且开始时将其置为空。
(2) 在子程序入口处设置一个标号(不妨设为L0)。
(3) 对子程序中的每一递归调用,用以下几个等价操作来替换:
(a)保留现场:开辟栈顶存储空间,用于保存返回地址(不妨用 Li,i=1,2,3,…)、调用层中的形参和局部变量的值(最外层调用不必考虑)。
(b)准备数据:为被调子程序准备数据,即计算实在参数的值, 并赋给对应的形参
(c)转入(子程序)执行, 即执行goto L0。
(d)在返回处设一个标号Li(i=1,2,3,…),并根据需要设置以下语句:若函数需要返回值,从回传变量中取出所保存的值并传送到相应的位置。
(4) 对返回语句,可用以下几个等价操作来替换:
如果栈不空,则依次执行如下操作,否则结束本子程序,返回。
(a)回传数据:若函数需要返回值,将其值保存到回传变量中。
(b)恢复现场:从栈顶取出返回地址(不妨保存到X中)及各
变量、形参值,并退栈。
(c)返回:按返回地址返回(即执行goto X)。
(5)对其中的非递归调用和返回操作可照搬。
流程图如下:
测试结果:
n=1时。
n=4时。
n=10时
源代码如下:
#include<iostream>
#include<stack>
using namespace std;
int digui(int n);//递归实现
int nodigui(int n);//不简化的递归等价转换
int jianhua_dg(int n);//简化的递归转换
int main()
{
cout << "请输入数列的层数n:";
int n;
cin >> n;
cout << "斐波那契数列为:" << digui(n) << endl;
cout << "斐波那契数列非递归调用为:" << nodigui(n) << endl;
cout << "斐波那契数列非递归简化后的调用结果为:" << jianhua_dg(n) << endl;
return 0;
}
int digui(int n)
{
if (n == 1 || n == 2)
return 1;
else
return digui(n - 1) + digui(n - 2);
}
int nodigui(int n)
{
if (n == 1 || n == 2)//相当于规则5照搬
return 1;
stack<int> s;//规则1
int s1 = 1, s2 = 1;//规则5
int ret;
L0://规则2
if(n>=3) //规则3
{
s.push(n);
s.push(1);//3.a
n -= 1;//3.b
goto L0;//3.c
L1: //3.d
s.push(n);//3.a
s.push(2);//3.a
n -= 2;//3.b
goto L0;//3.c
L2://3.d
ret = s1 + s2;//规则5
s2 = s1;
s1 = ret;
}
if (!s.empty())//规则4
{
int x;
x = s.top();//4.a
s.pop();//4.b
s.pop();//4.b
if(x == 1) goto L1;//4.c
else goto L2;//4.c
}
return ret;
}
int jianhua_dg(int n)
{
if (n == 1 || n == 2)
return 1;
int s1 = 1, s2 = 1;
int ret;
for (int i = 3; i <= n; i++)
{
ret = s1 + s2;
s2 = s1;
s1 = ret;
}
return ret;
}