算法--大數相乘

大數相乘

       大數相乘,簡單點就是說要相乘的兩個數數值過大,超過了計算機中數字的範圍,那麼就把乘數看成字符串來處理,計算出結果。那麼如何把整數看成字符串進行乘法運算並最終得到正確的結果呢,以及具體實現的代碼是怎樣的?接下來給大家詳細敘述。

       首先舉一個栗子(恩,栗子很好喫,明白了大數相乘後的感覺會比喫栗子的感覺更好)。爲了簡單的敘述清楚思路,就拿兩個簡單的數來做乘法吧。537*268。假設這兩個是大數,第一步,把兩個乘數看做字符串,並進行反轉,在這裏,字符串A是537,字符串B是268,進行反轉後,A[0]='7'  A[1]='3'  A[2]='5',B[0]='8'   B[1]='6'  B[2]='2'。第二步,用字符串B的每個元素分別去乘A中的每個元素,下標是從小到大,那麼就是  B[0]*A[0]   B[0]*A[1]    B[0]*A[2]  , B[1]*A[0]......以此類推,當然在這個過程中,還要記錄數據,接下來就是重要的部分了,雖然他們每個是字符元素,但是爲了敘述方便,我在下面就直接當做數字了(當然在代碼中會進行將字符轉換成數字的操作)。在每次字符串B下標轉換前,都要把積進位設爲0,和進位也設爲0(積進位就是兩個一位數相乘的時候的十位數,7*8=56,那麼5就是積進位,同理,7+8=15,那麼1就是和進位。如果相乘或相加結果是一位數,那麼積進位  和進位 均爲0)。

          B[0]*A[0]:

                   8*7+積進位=56+0=56

                   56/10=5-------------(爲B[0]*A[1]的積進位)

                   56%10=6------------(暫時結果)

                   本位+暫時結果+和進位=6(本位指的是他的前一輪計算得出的數字,因爲這是第一輪,當然是0了)

                   6/10=0---------------(爲B[0]*A[1]的和進位)

                   6%10=6---------------(本位的結果)

         B[0]*A[1]:

                   8*3+積進位=24+5=29

                   29/10=2---------------(爲B[0]*A[2]的積進位)

                   29%10=9--------------(暫時結果)

                   本位+暫時結果+和進位=9(本位依然爲0,因爲是第一輪,和進位是B[0]*A[0]得出來的)

                   9/10=0-----------------(爲B[0]*A[2]的和進位)

                   9%10=9-------------------(本位的結果)

       B[0]*A[2]:

                   8*5+積進位=40+2=42

                   42/10=4----------(因爲下次就是第二輪循環,所以這裏的積進位負責不了第二輪裏,等會直接與結果運算)

                   42%10=2----------(暫時結果)

                   本位+暫時結果+和進位=2

                  2/10=0---------------(和進位,同樣負責不了第二輪循環,等會與B[0]*A[2]的積進位進行運算)

                  2%10=2-------------(本位的結果)

       第一輪大循環結束,那麼要看B[0]*A[2]的進位情況,要在這輪就解決,因爲他們並不會進入到第二輪循環,那麼這裏的進位情況就是和進位+積進位=0+4=4。所以第一輪循環產生了四位數字-- 6924 (個位,十位,百位,千位排列)

      接着進行下一輪循環,同樣開始把積進位,和進位初始化爲0  

       B[1]*A[0]:

            6*7+積進位=42

            42/10=4-------(爲B[1]*A[1]的積進位)

            42%10=2-------(暫時結果)

           本位+暫時結果+和進位=9+2+0=11(解釋一下本位,這是第二輪循環,所以他們有本位,即上一輪的結果。本位就是在進行和運算時,結果要與哪一位對齊。因爲這是第二輪循環,那麼就是與十位對齊,個位空出來。每一輪先算出來的本位是按照位數從低到高算出來的,所以先算出來個位,再是十位,百位,千位.....那麼B[1]*A[0]的本位就是9。如果不理解,最後我上圖,見圖-1

           11/10=1-----(爲B[1]*A[1]的和進位)

           11%10=1-----(本位)

        B[1]*A[1]........................................................

        B[1]*A[2].........................................................

        以此類推,那麼第二輪產生的數字1563(0)(個位,十位,百位,千位排列)

        接下來是第三次循環,同樣開始把積進位,和進位初始化爲0   

           B[2]*A[0]...........................................

           B[2]*A[1]...........................................

           B[2]*A[2]...........................................

      以此類推,第三輪的結果9341(00).

     那麼現在循環結束,第三輪的結果是1439(00)。爲什麼會有(00),因爲第三輪向前進了兩位,那麼缺少的這兩位分別是第二輪循環中的B[1]*A[0]的本位(1),B[0]*A[0]的本位(6)。所以最終結果是143916。接下來上圖:

  

       在這個式子中,只是把第一輪循環中的積進位標了出來,至於剛纔說的本位,看第二輪循環中,低位的2的本位就是他上面的9。恩,就是這個意思,錯開一位,大家在乘法也都這樣做的。理解這個思路最好的方法就是按照這樣的式子,進行一次運算,去理解每輪循環中的和進位,積進位,本位結果。思路說的比較繁瑣,不知道大家有沒有品嚐到栗子的美味,還是覺得品嚐到了比栗子還要美好的味道。

     

         

                  


#include<stdio.h>

#include<string.h>

#include<stdlib.h>
char c[100000];
void reverse(char c[],int low,int high)
{
    char temp;
    while(low<high)
    {
        temp=c[low];
        c[low]=c[high];
        c[high]=temp;
        low++;
        high--;
    }
}
void multiply(char a[],char b[])
{
    int m=strlen(a);
    int n=strlen(b);
    memset(c,'0',m+n);
    c[m+n]='\0';
    reverse(a,0,m-1);
    reverse(b,0,n-1);
    int multiFlag;
    int addFlag;
    int i,j;
    for(i=0;i<m;i++)
    {
        multiFlag=0;
        addFlag=0;
        for(j=0;j<n;j++)
        {
           int temp1=(b[j]-'0')*(a[i]-'0')+multiFlag;

           multiFlag=temp1/10;

           int temp2=temp1%10;

           int temp3=(c[i+j]-'0')+temp2+addFlag;

           addFlag=temp3/10;

           c[i+j]=temp3%10+'0';

        }
        c[i+n]=addFlag+multiFlag+'0';
    }
}
int main()
{
    char a[]="537";
    char b[]="268";
    int i;
    multiply(a,b);
    reverse(c,0,strlen(c)-1);
    for(i=0;i<strlen(c);i++)
    {
        printf("%c",c[i]);
    }
    printf("\n");
    return 0;
}



發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章