递归程序的优化,各位帮忙看一下...

seqingzi 2010-05-21 03:12:09
自己写的一个加密程序...各个函数之间调用,差不多每个函数都有不同的递归情况.效率极其差劲...有什么优化的方法?
想利用一个备忘录,把第一次递归的结果存入其中,计算第二个结果的时候调用,第二个结果计算完毕,结果存入备忘录,覆盖以前数据,如此往复..具体如何实现?
以下是源代码:
#include <stdio.h>
double b ,x0;
int px(int i);
int calc_f(int i);
int calc_g(int i);
double calc_x(int i);
int i;
int px(int t) //2的指数函数
{
int a,r,b =1;
if(t == 0)
return 1;
for(a = 1;a<=t;a++)
{
r = b*2;
b = r;
}
return b;
}
int calc_f ( int i )
{
int j,k,c = 0;
double xi;
if(i == 0) //取得待处理浮点数 xi
xi = x0;
else
xi = calc_x(i-1);
bool datal[15] ,datam[15] ,datah[15],datax[45],dataf[15];
int calc[15];
for(j = 0;j<45;j++)//把浮点数小数部分的前45位存入datax[45]
{
if(xi*2 >1)
{
datax[j] = 1;
xi = xi*2 -1;
}
else
{
datax[j] = 0;
xi = xi*2 ;
}
}
for(j = 0;j<15;j++) //把1~15位赋给datal,16~30位赋给datam,31~45位赋给datah
{
datal[j] = datax[j] ;
datam[j] = datax[j+15] ;
datah[j] = datax[j+30] ;
}
for(j = 0;j<15;j++) //datal,datam,datax异或,异或值1~15位表示一个15位二进制数的各个位,求出这个数
{
dataf[j] = datal[j]^datam[j]^datah[j] ;
calc[j] = dataf[j]*px(14-j) ;
c = c +calc[j];
}
return c;
}
int calc_g ( int i ) //实现g(i) = f(1)^f(2)^...^f(i) = g(i-1)^f(i)
{
if( i == 0)
return calc_f ( 0 );
else
return (calc_g( i -1 )^ calc_f( i ));
}
double calc_x (int i) //计算calc_f(i)函数所需要的xi变量
{
int j,ki;
double x_next , x_now ;
int g = calc_g(i) ; //调用calc_g(i)
int noise = 5 ; //这里本来是用一个noise函数。。无奈递归调用太多,直接栈溢出了
ki = ( g ^ noise ) % 73;//计算(计算x_next)需要循环的次数
if(i == 0) //由xi计算xi+1,函数返回值为x_next=xi+1
x_now = x0;
else
x_now = calc_x(i-1);
for(j = 0;j < ki;j++)
{
x_next = b * x_now * ( 1 - x_now );
x_now = x_next ;
}
return x_next;
}
main() //查看函数执行情况
{
x0 = 0.4234235,b = 3.6575757;
for(i = 0;i<15;i++)
{
calc_f(i);
calc_g(i);
calc_x(i);
}
for(i = 0;i<15;i++)
{
printf("%8d",calc_f(i));
printf("%8d",calc_g(i));
printf("%15f\n",calc_x(i));
}
}
...全文
84 3 打赏 收藏 转发到动态 举报
写回复
用AI写文章
3 条回复
切换为时间正序
请发表友善的回复…
发表回复
seqingzi 2010-05-21
  • 打赏
  • 举报
回复
谢谢technic_tec。
备忘录的部分已经解决了,想把递归转换为非递归,能否告诉大致思路,站内PM我,如若有空的话。
technic_tec 2010-05-21
  • 打赏
  • 举报
回复
1) px可以用移位代替, px(i)=(1<<i), a*px(i)=(a<<i);
2) 用3个备忘录,分别存储calc_f/calc_g/calc_x的结果;对于每个可能的参数i只计算1次,后续调用直接取存储的值。这个方法只适用于确定性算法,即要求calc_f/calc_g/calc_x对同一参数始终返回相同的结果(不含随机数/伪随机数/静态变量)。

#include <stdio.h>
#include <string.h>
double b ,x0;
int px(int i);
int calc_f(int i);
int calc_g(int i);
double calc_x(int i);
int i;
int px(int t) //2的指数函数
{
int a,r,b =1;
if(t == 0)
return 1;
for(a = 1;a<=t;a++)
{
r = b*2;
b = r;
}
return b;
}
#define N 16

//vf/vg/vx 存储 calc_f/calc_g/calc_x的结果
//bf/bg/bx 标识对应结果是否已计算过
int vf[N], vg[N];
double vx[N];
bool bf[N], bg[N], bx[N];

int calc_f ( int i )
{
int j,k,c = 0;
double xi;
if(bf[i]) return vf[i];
if(i == 0) //取得待处理浮点数 xi
xi = x0;
else
xi = calc_x(i-1);
bool datal[15] ,datam[15] ,datah[15],datax[45],dataf[15];
int calc[15];
for(j = 0;j<45;j++)//把浮点数小数部分的前45位存入datax[45]
{
if(xi*2 >1)
{
datax[j] = 1;
xi = xi*2 -1;
}
else
{
datax[j] = 0;
xi = xi*2 ;
}
}
for(j = 0;j<15;j++) //把1~15位赋给datal,16~30位赋给datam,31~45位赋给datah
{
datal[j] = datax[j] ;
datam[j] = datax[j+15] ;
datah[j] = datax[j+30] ;
}
for(j = 0;j<15;j++) //datal,datam,datax异或,异或值1~15位表示一个15位二进制数的各个位,求出这个数
{
dataf[j] = datal[j]^datam[j]^datah[j] ;
calc[j] = (dataf[j]<<(14-j)) ;
c = c +calc[j];
}
vf[i] = c;
bf[i] = true;
return c;
}
int calc_g ( int i ) //实现g(i) = f(1)^f(2)^...^f(i) = g(i-1)^f(i)
{
if(bg[i]) return vg[i];
if( i == 0)
vg[i] = calc_f ( 0 );
else
vg[i] = (calc_g( i -1 )^ calc_f( i ));
bg[i] = true;
return vg[i];
}
double calc_x (int i) //计算calc_f(i)函数所需要的xi变量
{
int j,ki;
double x_next , x_now ;
if(bx[i]) return vx[i];
int g = calc_g(i) ; //调用calc_g(i)
int noise = 5 ; //这里本来是用一个noise函数。。无奈递归调用太多,直接栈溢出了
ki = ( g ^ noise ) % 73;//计算(计算x_next)需要循环的次数
if(i == 0) //由xi计算xi+1,函数返回值为x_next=xi+1
x_now = x0;
else
x_now = calc_x(i-1);
for(j = 0;j < ki;j++)
{
x_next = b * x_now * ( 1 - x_now );
x_now = x_next ;
}
vx[i] = x_next;
bx[i] = true;
return x_next;
}
main() //查看函数执行情况
{
memset(bf, 0, sizeof(bf));
memset(bg, 0, sizeof(bg));
memset(bx, 0, sizeof(bx));
x0 = 0.4234235,b = 3.6575757;
for(i = 0;i<15;i++)
{
calc_f(i);
calc_g(i);
calc_x(i);
}
for(i = 0;i<15;i++)
{
printf("%8d",calc_f(i));
printf("%8d",calc_g(i));
printf("%15f\n",calc_x(i));
}
}
fire_woods 2010-05-21
  • 打赏
  • 举报
回复
calc_g直接循环就是了.

33,006

社区成员

发帖
与我相关
我的任务
社区描述
数据结构与算法相关内容讨论专区
社区管理员
  • 数据结构与算法社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧