高精度乘法(C++和Java實現)

輸入格式

兩行,兩個整數。

輸出格式

一行一個整數表示乘積。

每個數字不超過 10^2000

簡單思路

完全模擬筆算中乘法的步驟。第一個數的字符長度爲lena,第二個爲lenb.,先開足夠大的二維數組num[10000][10000],

將第一個數的每一位與第二個數的位依次相乘,結果存放在num數組的第1行,

接着將第一個數的每一位與第二個數的位依次相乘,結果存放在num數組的第2行,

........

將第一個數的每一位與第二個數的最高位依次相乘,結果存放在num數組的第lenb行,

依次類推,注意每次都有一個向左偏移一位的操作,用一個變量控制即可。

以111*111爲例,實際存放中間值的二維數組中是這樣的(沒賦值的地方都爲'\0'):

不難推出真正有效的二維數組範圍只有number[lena+lenb-1][lenb],最開始開的number[10000][10000]除了有效範圍剩下的全是'\0';

 

‘\0’

‘\0’

1

1

1

‘\0’

1

1

1

‘\0’

1

1

1

‘\0’

‘\0’

然後依次掃描二維數組的每一列,將每一列累加(如果遇到\0則跳過)結果s存放在ans[i]中,如果s>10,則需要進位處理,s<10則不用進位,最後依次輸出ans數組中的各位數就行了。

AC代碼:

#include<iostream>
#include<string>
using namespace std;
int num[10000][10000];string a,b;
int main()
{
    cin>>a>>b;
    if(a[0]=='0'||b[0]=='0')//如果a,b中有一個爲0,則答案爲0退出程序
    {
        cout<<0;
        return 0;
    }
    int lena=a.length();
    int lenb=b.length();
    int m=0;
    int i,j;
    for(i=lenb-1;i>=0;i--)
    {
        int k=lenb-i-1;//k控制偏移
        int add=0;
        for(j=lena-1;j>=0;j--)
        {
            int s=(a[j]-'0')*(b[i]-'0')+add;
            if(s<10)
            {
                num[m][k++]=s;
                add=0;
            }
            else
            {
                num[m][k++]=s%10;
                add=s/10;
            }
        }
        num[m][k++]=add;
        m++;
    }
    int ans[20000];int k=0;int add=0;
    for(j=0;j<lenb+lena+1;j++)
    {
        int sum=0;
        for(i=0;i<lenb;i++)
        {
            if(num[i][j]!='\0')
               sum+=num[i][j];
        }
        sum+=add;
    if(sum>=10)
    {

        ans[k++]=sum%10;
        add=sum/10;   
    }
    else
    {
        ans[k++]=sum;
        add=0;
    }
    }
if(add!=0)
    ans[k++]=add;

if(ans[k]==0)//去掉前導0(此代碼輸出有時會產生含有前導0的002834這種數
{
    while(ans[k]==0)
        k--;
}
for(i=k;i>=0;i--)
    cout<<ans[i];
}
import  java.util.*;
public class Main {
    public static void main(String[] args) {
        String str;
        int[][] number =new int[10000][10000];
        char[] a=new char[2000];char[] b=new char[2000];
        Scanner in = new Scanner(System.in);

        int i;
        str=in.nextLine();
        for(i=0;i<str.length();i++)
            a[i]=str.charAt(i);
        int lena=str.length();

        str=in.nextLine();
        for(i=0;i<str.length();i++)
            b[i]=str.charAt(i);
        int lenb=str.length();
        if(a[0]=='0'||b[0]=='0') {//如果a,b中有一個爲0,則答案爲0退出程序
            System.out.print(0);
            System.exit(0);
        }
        int m=0;
        int j;
        for(i=lenb-1;i>=0;i--) {
            int k=lenb-i-1;//k控制偏移
            int add=0;
            for(j=lena-1;j>=0;j--) {
                int s = (a[j] - '0') * (b[i] - '0') + add;
                if (s < 10) {
                    number[m][k++] = s;
                    add = 0;
                } else {
                    number[m][k++] = s % 10;
                    add = s / 10;
                }
            }
                number[m][k++]=add;
                m++;
        }
        int []ans=new int[20000];int k=0;int add=0;
        for(j=0;j<lenb+lena+1;j++) {
            int sum=0;
            for(i=0;i<lenb;i++) {
                if(number[i][j]!='\0')
                    sum+=number[i][j];
            }
            sum+=add;
            if(sum>=10) {
                ans[k++]=sum%10;
                add=sum/10;
            }
            else {
                ans[k++]=sum;
                add=0;
            }
        }
        if(add!=0)
            ans[k++]=add;

        if(ans[k]==0){//去掉前導0(此代碼有時會產生含有前導0例如002834
            while(ans[k]==0)
                k--;
        }
        for(i=k;i>=0;i--)
                System.out.print(ans[i]);
    }
}

 

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