高精度乘法(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]);
    }
}

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值