1. 程式人生 > 其它 >c語言求兩個超大整數相乘的積(陣列)

c語言求兩個超大整數相乘的積(陣列)

技術標籤:C語言演算法c++字串

一、用整型陣列儲存兩個大整數,再逐個相乘,最後進位:

1、先來個例子,計算a*b=c,理解陣列中的每位數逐個相乘的步驟:

求987*654;利用陣列計算,則a[0]=9,a[1]=8,a[2]=7;b[0]=6,b[1]=5,b[2]=4;

第一趟計算,用9分別與6、5、4相乘,得:c[0+0]=54,c[0+1]=45,c[0+2]=36;

第二趟計算,用8分別與6、5、4相乘,得:c[1+0]=48,c[1+1]=40,c[1+2]=32;

第三趟計算,用7分別與6、5、4相乘,得:c[2+0]=42,c[2+1]=35,c[2+2]=28;

將陣列c中下標相同的數相加,得到:

c[0]=54,

c[1]=45+48=93,

c[2]=36+40+42=118,

c[3]=32+35=67,

c[4]=28;

所以可以總結出,如果要用表示式表示c[]的話,則c[i+j]=c[i+j]+a[i]*b[j],其中c[]的各項初始值為0;

假設陣列a[]和b[]的實際長度分別為len1、len2,則有表示式:

for(i=0;i<len1;i++)
{
    for(j=0;j<len2;j++)
    {
        c[i+j]+=a[i]*b[j];
    }
}

2.對上述得到的陣列c[i]從右至左進行進位處理(取整和取餘):

第一步,令i=4,則

c[3]=67+28/10=69;

c[4]=28%10=8;

第二步,令i=3,則

c[2]=118+69/10=124;

c[3]=69%10=9;

第三步,令i=2,則

c[1]=93+124/10=105;

c[2]=124%10=4;

第四步,令i=1,則

c[0]=54+105/10=64;

c[1]=105%10=5;

綜上,進位後的陣列c[]={64,5,4,9,8},正序輸出c[]即為大整數a與b的乘積;

假設陣列c的實際長度為len3,則有表示式

for(i=len3-1;i>0;i--)
{
    c[i-1]+=c[i]/10;
    c[i]=c[i]%10;
}

二、根據上述思路,進行程式碼編寫:

1、編寫程式碼需要考慮以下幾個問題:

(1)要按照字串的形式來儲存大整數a和b,則需先定義兩個記憶體足夠大的字串陣列來接收這兩個數;

(2)如何獲取這兩個陣列的實際長度?用strlen()函式;

(3)字元型陣列如果直接進行乘法運算,結果會出錯,所以還要將字元型陣列轉化成整型陣列;

(3)如何知道相乘之後的結果陣列的實際長度?通過找規律可知,結果陣列的長度=兩個大整數陣列長度之和-1;

(4)如何正序輸出結果陣列的各項值?這個方法很多,下標法或指標法都可以。

2.程式碼部分(codeblocks可執行):

#include<stdio.h>
#include<string.h>
#define N 100
int main()
{
    //將兩個大整數分別存入字串陣列num1和num2中
    char num1[N]={'\0'},num2[N]={'\0'};//初始化,如果不初始化也可以的,直接定義;
    int n1[N],n2[N],n3[2*N]={0};//整型陣列n3[]必須進行初始化,否則後面逐個計算時會出錯!!!
    int a,b,c;
    int i,j;
    printf("請輸入兩個大整數:\n");
    scanf("%s%s",&num1,&num2);//獲取陣列,加不加&都可以
    a=strlen(num1);//計算字串陣列num1的長度
    b=strlen(num2);//計算字串陣列num2的長度
    c=a+b-1;//n1*n2得到的結果陣列n3的長度

    //將字串陣列轉化成整型陣列
    for(i=0;i<a;i++)
    {
        n1[i]=num1[i]-'0';
    }
    for(i=0;i<b;i++)
    {
        n2[i]=num2[i]-'0';
    }
    //逐個相乘
    for(i=0;i<a;i++)
    {
        for(j=0;j<b;j++)
        {
            n3[i+j]+=n1[i]*n2[j];//這裡要用到n3[0]~n3[c-1]的初始值,所以陣列n3[2*N]必須初始化,否則容易計算出錯
        }
    }
    //對陣列n3中的資料至右向左進位
    for(i=c-1;i>0;i--)
    {
        n3[i-1]+=n3[i]/10;
        n3[i]=n3[i]%10;
    }
    //正向輸出結果陣列n3
    printf("輸出兩個大整數相乘的積:\n");
    for(i=0;i<c;i++)
    {
        printf("%d",n3[i]);
    }
    printf("\n");
    return 0;
}

執行結果:

寫在最後:剛開始執行時程式的結果總是不對,我也不知道是哪部分的問題,只能一小塊一小塊地試,發現將字元陣列轉化成整型陣列這一步是必須的,不能省;陣列的長度賦值給整型變數會更好,不建議直接放在for迴圈裡;最後最最重要的就是,儲存結果的整型陣列一定要進行初始化,不然怎麼算都不對,所以說保持良好的初始化習慣真的挺好。

思路參考歐陽田的文章https://blog.csdn.net/outsanding/article/details/79472376