大整數乘法實現

給兩個用字符串表示的大整數,對這兩個整數進行相乘,求它們的積,所謂大整數就是用int,long均無法表示的整數,對它們做乘法,只能自己來實現。

我們假定兩個整數是十進制的正數,我們做這樣的假定只是爲了研究大整數乘法的方法,至於其他進制,有正負之分只要在這種方法上稍微做點修改就行了。下面開始講解。

1.方法1兩個數相乘,最先想到的方法就是,我們可以用加法來實現,對被乘數做乘數次加法,進行一個循環就可以很容易的得到。當然這個方法可以做一個優化,對於輸入的兩個字符串整數,可以先比較一下兩個數的大小,用較小的數做乘數,這樣可以減少循環的次數。比較兩個數的大小比較容易,第一步先比較兩個數的長度,較短的數小;如果長度相同就比較兩個數的第一個字符,如果有一個較小,就用那個數作爲乘數;如果長度相同且第一個字符也相同,我們就隨便選擇一個作爲被乘數。如果要完整的實現這個方法,需要定義字符串表示整數的加法運算和減法運算。這種方法雖然能夠實現兩個整數的乘法但是缺點也是明顯的,那就是循環的次數過多。加入被乘數的長度是N,乘數的長度是M,壞的情況下,循環的次數是10的M次方-1,在計算的過程中每次循環需要對被乘數的操作次數爲N+M/2次,需要對乘數測操作次數是M/2次,這樣時間複雜度就爲10的M次方(N + M)。這個複雜度是很難讓人接受的。

2.方法1我們算是一種比較基本的方法,它的缺陷也是很明顯的,有沒有一種很好的方法呢?當然有的,第二種方法,我們不再循環乘數次,對被乘數進行加法操作。先保存一份被乘數副本,我們從乘數的個位開始,取得個位上的數字,假設爲a, 對被乘數進行a次自加操作,將結果保存起來,重新加載一次被乘數;然後取乘數十位上的數字,假設爲b,先將被乘數左移一位,對被原先乘數進行b次循環自加;最後將結果與第一次保存的結果向加。一次次執行這種操作,直到循環乘數的位數次,結束。被乘數保存的值就是相乘的結果值。這種方法的性能就比較好了,對乘數和被乘數分別進行了乘數位數次循環,對被乘數進行了乘數上所有位上數字的和的次循環自加。

3.還有沒有比方法2更好的辦法呢?答案是肯定的,這種方法是對方法2自加一步進行了優化,在每次取個位上數字之後,假設爲a, 不在對被乘數進行a次自加,而是將a與被乘數上的每位進行相乘,相乘之後再加上低位上的進位,得到的結果除於10得到向高位的進位,與10取餘得到該位的數字,依次對被乘數上的每位上的數進行這個操作。這樣下來,我們僅對被乘數進行了乘數的位數次循環,每次循環對僅對乘數上的每位數進行了一次操作。這種方法的時間複雜度是不是非常低了。

利用上述方法,經過進一步的改進就可以解決其他進制的乘法,也可以解決有正負之分的乘法。

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