存储检索是指,在检索中记录检索结果,在下次检索中计算出其结果的情况下,可以直接拿来使用。
板栗:
现有的问题要求写输出第n个斐波那契数列的函数。
斐波那契数列如下。 一,一,二,三,五,八……。
直接方法只要打开数组,计算斐波那契数列到第n个,输出array[n]即可
intf(intn ) {
intf ibo [ maxn ]={ 0,1 };
for(inti=2; i=n; I )
fibo[i]=fibo[i-2] fibo[i-1];
returnfibo[n];
}
当前要求:必须使用递归!
问题还是很简单的。 斐波那契数列的递归定义为f(0)=0,f(0)=1,f(0 ) )=f(n-1 ) f(0 ) n-2 ) (n=2,nN* ),可以根据该定义编写程序
intf(intn ) {
if(n==0||n==1) return1; //递归终点
Elsereturnf(n-1 ) f ) n-2;
}
但是这里有问题。 例如,在n=5的情况下,在递归式中需要计算f(4)和f(4),另外在计算f ) 4时需要计算f(4和f )2),会产生计算的重复,以使时间的复杂度为指数函数级o ) 2n
为了避免计算重复,必须创建新数组以保存计算结果
intdp[MAXN]={0};
intf(intn ) {
if(n==0||n==1) return1; //递归边界
if(DP[n]==0) ) ) ) ) ) )。
DP[n]=f(n-1 ) f ) n-2; //如果没有计算过,就计算那个
算了的话,就不用算了
//最后返回DP [ n ]
返回DP [ n ];
}
由此,能够大幅降低时间的复杂性,降低到o(n )
试着写一个运行需要时间的程序吧。
#包含
#包含
#defineMAXN100
intdp[MAXN]={0};
intF1(intn ) {
if(n==0||n==1) return1; //递归边界
if(DP[n]==0) ) ) ) ) ) )。
DP[n]=F1(N-1 ) f1 (n-2 ); //如果没有计算过,就计算那个
算了的话,就不用算了
//最后返回DP [ n ]
返回DP [ n ];
}
intF2(intn ) {
if(n==0||n==1) return1; //递归终点
ELSEreturnF2(n-1 ) F2 ) n-2;
}
intmain () )。
intn;
clock_tstart,stop;
scanf('%d ',n );
开始=时钟(;
printf(%d(n )、F2 (n ) );
停止=时钟(;
printf(F2小时: %.0Fms(n ),double ) )停止-开始) *1000/CLOCKS_PER_SEC ) );
开始=时钟(;
printf(%d(n ),f1 ) n );
停止=时钟(;
printf(f1需要时间(%.0fms(n ),double ) ) stop-start ) *1000/CLOCKS_PER_SEC );
返回0;
}
执行结果: