三、遞推法
遞推法是利用問題本身所具有的一種遞推關係求問題解的一種方法。設要求問題規模為N的解,當N=1時,解或為已知,或能非常方便地得到解。能採用遞推法構造算法的問題有重要的遞推性質,即當得到問題規模為i-1的解後,由問題的遞推性質,能從已求得的規模為1,2,…,i-1的一系列解,構造出問題規模為I的解。這樣,程序可從i=0或i=1出發,重複地,由已知至i-1規模的解,通過遞推,獲得規模為i的解,直至得到規模為N的解。
【問題】 階乘計算
問題描述:編寫程序,對給定的n(n≦100),計算並輸出k的階乘k!(k=1,2,…,n)的全部有效數位。
由於要求的整數可能大大超出一般整數的位數,程序用一維陣列儲存於長整數,儲存於長整數陣列的每個元素只儲存於長整數的一位數位。如有m位成整數N用陣列a[ ]儲存於:
N=a[m]×10m-1+a[m-1]×10m-2+ … +a[2]×101+a[1]×100
並用a[0]儲存於長整數N的位數m,即a[0]=m。按上述約定,陣列的每個元素儲存於k的階乘k!的一位數位,並從低位元到高位依次存於陣列的第二個元素、第三個元素……。例如,5!=120,在陣列中的儲存於形式為:
3 0 2 1 ……
首元素3表示長整數是一個3位數,接著是低位元到高位依次是0、2、1,表示成整數120。
計算階乘k!可採用對已求得的階乘(k-1)!連續累加k-1次後求得。例如,已知4!=24,計算5!,可對原來的24累加4次24後得到120。細節見以下程序。
# include <stdio.h>
# include <malloc.h>
# define MAXN 1000
void pnext(int a[ ],int k)
{ int *b,m=a[0],i,j,r,carry;
b=(int * ) malloc(sizeof(int)* (m+1));
for ( i=1;i<=m;i++) b=a;
for ( j=1;j<=k;j++)
{ for ( carry=0,i=1;i<=m;i++)
{ r=(i<a[0]?a+b:a)+carry;
a=r%10;
carry=r/10;
}
if (carry) a[++m]=carry;
}
free(b);
a[0]=m;
}
void write(int *a,int k)
{ int i;
printf(「%4d!=」,k);
for (i=a[0];i>0;i--)
printf(「%d」,a);
printf(「\n\n」);
}
void main()
{ int a[MAXN],n,k;
printf(「Enter the number n: 「);
scanf(「%d」,&n);
a[0]=1;
a[1]=1;
write(a,1);
for (k=2;k<=n;k++)
{ pnext(a,k);
write(a,k);
getchar();
}
}
|