回覆列表
  • 1 # 變餅檔

    由於要求的整數可能大大超出一般整數的位數,程式用一維陣列儲存長整數,儲存長整數陣列的每個元素只儲存長整數的一位數字。如有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;

    }

  • 中秋節和大豐收的關聯?
  • 韓信是如何為劉邦分析楚漢之爭的形式的?