由於要求的整數可能大大超出一般整數的位數,程式用一維陣列儲存長整數,儲存長整數陣列的每個元素只儲存長整數的一位數字。如有m位成整數N用陣列a[]儲存:
N=a[m]×10^(m-1)+a[m-1]×10^(m-2)+ … +a[2]×10^1+a[1]×10^0
並用a[0]儲存長整數N的位數m,即a[0]=m。按上述約定,陣列的每個元素儲存k的階乘k!的一位數字,並從低位到高位依次存於陣列的第二個元素、第三個元素……。例如,5!=120,在陣列中的儲存形式為:
3 0 2 1 ……
對應:a[0] a[1] a[2] a[3]
首元素3表示長整數是一個3位數,接著是低位到高位依次是0、2、1,表示成整數120。
計算階乘k!可採用對已求得的階乘(k-1)!連續累加k-1次(即k個(k-1)!相加)後求得。例如,已知4!=24,計算5!,可對原來的24累加4次24後得到120。對應程式如下:
#include <stdio.h>
#include <malloc.h>
#define MAXN 1000
/*factorial:求k的階乘:連續加(k-1)次(k-1)!,便得到了k!
結果儲存在陣列a中。a[0]為結果的位數,其後
下標從小到大表示階乘的低位到高位
*/
void factorial(int a[],int k)
{
int *b,m=a[0],i,j,r,carry;
b=(int * ) calloc(m+1, sizeof(int));
for ( i=1;i<=m;i++) //儲存a原來的值,用來加。a儲存累加的結果
b[i]=a[i];
for ( j=1;j<k;j++) //上一次階乘的值加(k-1)次
for ( carry=0,i=1;i<=m;i++) //從第一位開始,到最後一位止,依次加(k-1)!中對應數字
{//如果累加得到的位數m大於原來的位數a[0],多出來的位應不斷加上進位的值
r=(i<=a[0]?a[i]+b[i]:a[i])+carry;
a[i]=r%10; //求餘位
carry=r/10; //求進位的值
}
if (carry) a[++m]=carry; //最後一次處理
a[0]=m; //用新的位數值m來更新a[0],以防m有增加。
free(b);
/*printFactorial:列印陣列a中儲存的k的階乘的結果*/
void printFactorial(int *a,int k)
int i;
printf("%4d!=",k);
for (i=a[0];i>0;i--) //從高位到低位列印階乘的結果
printf("%d",a[i]);
printf("\n");
//主函式
int main()
int a[MAXN]={0},n,k;
printf("====用遞推法求階乘====\n");
printf("請輸入正整數n: "); //輸入n,求n!
scanf("%d",&n);
a[0]=1; //初始化,1的階乘是1位
a[1]=1; //1!的值為1
printFactorial(a,1); //列印它的結果
for (k=2;k<=n;k++)
factorial(a,k); //利用上次的結果來求k!
printFactorial(a,k); //每次都列印k!
return 0;
由於要求的整數可能大大超出一般整數的位數,程式用一維陣列儲存長整數,儲存長整數陣列的每個元素只儲存長整數的一位數字。如有m位成整數N用陣列a[]儲存:
N=a[m]×10^(m-1)+a[m-1]×10^(m-2)+ … +a[2]×10^1+a[1]×10^0
並用a[0]儲存長整數N的位數m,即a[0]=m。按上述約定,陣列的每個元素儲存k的階乘k!的一位數字,並從低位到高位依次存於陣列的第二個元素、第三個元素……。例如,5!=120,在陣列中的儲存形式為:
3 0 2 1 ……
對應:a[0] a[1] a[2] a[3]
首元素3表示長整數是一個3位數,接著是低位到高位依次是0、2、1,表示成整數120。
計算階乘k!可採用對已求得的階乘(k-1)!連續累加k-1次(即k個(k-1)!相加)後求得。例如,已知4!=24,計算5!,可對原來的24累加4次24後得到120。對應程式如下:
#include <stdio.h>
#include <malloc.h>
#define MAXN 1000
/*factorial:求k的階乘:連續加(k-1)次(k-1)!,便得到了k!
結果儲存在陣列a中。a[0]為結果的位數,其後
下標從小到大表示階乘的低位到高位
*/
void factorial(int a[],int k)
{
int *b,m=a[0],i,j,r,carry;
b=(int * ) calloc(m+1, sizeof(int));
for ( i=1;i<=m;i++) //儲存a原來的值,用來加。a儲存累加的結果
b[i]=a[i];
for ( j=1;j<k;j++) //上一次階乘的值加(k-1)次
{
for ( carry=0,i=1;i<=m;i++) //從第一位開始,到最後一位止,依次加(k-1)!中對應數字
{//如果累加得到的位數m大於原來的位數a[0],多出來的位應不斷加上進位的值
r=(i<=a[0]?a[i]+b[i]:a[i])+carry;
a[i]=r%10; //求餘位
carry=r/10; //求進位的值
}
if (carry) a[++m]=carry; //最後一次處理
}
a[0]=m; //用新的位數值m來更新a[0],以防m有增加。
free(b);
}
/*printFactorial:列印陣列a中儲存的k的階乘的結果*/
void printFactorial(int *a,int k)
{
int i;
printf("%4d!=",k);
for (i=a[0];i>0;i--) //從高位到低位列印階乘的結果
printf("%d",a[i]);
printf("\n");
}
//主函式
int main()
{
int a[MAXN]={0},n,k;
printf("====用遞推法求階乘====\n");
printf("請輸入正整數n: "); //輸入n,求n!
scanf("%d",&n);
a[0]=1; //初始化,1的階乘是1位
a[1]=1; //1!的值為1
printFactorial(a,1); //列印它的結果
for (k=2;k<=n;k++)
{
factorial(a,k); //利用上次的結果來求k!
printFactorial(a,k); //每次都列印k!
}
return 0;
}