遞歸有時候會出現重複計算的情況(如下例題),因此爲了提高代碼效率,就需要進記憶性遞歸——即只對第一次出現的新數據進行計算並進行保存,而對於已經計算過的結果,只需將結果取出即可。(它可以提高效率,避免計算機進行重複已做過的完全相同的工作而降低效率)
例1:
我們要求找出具有下列性質數的個數(包含輸入的自然數n):
先輸入一個自然數n(n≤1000),然後對此自然數按照如下方法進行處理:
不作任何處理;
在它的左邊加上一個自然數,但該自然數不能超過原數的一半;
加上數後,繼續按此規則進行處理,直到不能再加自然數爲止.
輸入格式
1個自然數n(n≤1000)
輸出格式
1個整數,表示具有該性質數的個數。
樣例:
輸入 #1
6
輸出 #1
6
#include<stdio.h>
int f[1002]={0};
int num(int n)
{
f[1]=1;
int i,sum=1;
if(n==1){
return f[n];
}
else{
if(f[n]==0){//如果沒做這個數的計算,就進行新計算,並進行保存
for(i=1;i<=n/2;i++){
sum+=num(i);
}
return f[n]=sum;
}
else{//對於求解過的n,直接取保存的結果即可
return f[n];
}
}
}
int main()
{
int n;
scanf("%d",&n);
printf("%d",num(n));
return 0;
}
例2:
斐波那契數列:
#include<stdio.h>
int f[100]={0};
int Fibonacci(int n)
{
if(n==1||n==2)
return f[n]=1;
else{
if(f[n]==0) //沒求解過
return f[n]=Fibonacci(n-1)+Fibonacci(n-2);
else //求解過,直接取保存的結果值
return f[n];
}
}
int main()
{
printf("%d\n",Fibonacci(1000));
return 0;
}
再來看看遞歸的斐波那契數列寫法:(當然還有數組循環的寫法也比遞歸更有效率)
#include<stdio.h>
int Fibonacci(int n)
{
if(n==1||n==2)
return 1;
else
return Fibonacci(n-1)+Fibonacci(n-2);
}
int main()
{
for(int i=1;i<100;i++){
printf("%d ",Fibonacci(i));
}
printf("\n");
return 0;
}
總結:遞歸不一定提高效率。它優點在於,將複雜問題簡單化,“大事化小,小事易做”。