算法设计实验一大整数乘法

问题描述

求两个不超过200位的非负整数的积。

输入形式

有两行,每行是一个不超过200位的非负整数,没有多余的前导0。

输出形式

一行,即相乘后的结果。结果里不能有多余的前导0,即如果结果是342,那么就不能输出为0342。

样例输入

1234567890

9876543210

样例输出

12193263111263526900

 

 

由于这道题利用分治的方法解决,但是其中仍然设计大数乘法,因此我采用

java 利用其中的 BigInteger 来解决这道问题

下面是理想情况的(两个数的位数长度相等并且均为 2 的幂次)的推导

具体的计算是参考公式

用分治法来解

直接看注释吧

import java.math.BigInteger;
import java.util.Scanner;

public class 大整数相乘 {
    static BigInteger a,b;
    static BigInteger duan(BigInteger a){//用来判断大整数正负
        if(a.compareTo(BigInteger.ZERO)>0){
            return BigInteger.ONE;
        }else{
            return new BigInteger("-1");
        }
    }
    static public BigInteger unsame(BigInteger a,BigInteger b,int n1,int n2){
        BigInteger sign=duan(a).multiply(duan(b));用来考虑计算结果的正负
        a=a.abs();
        b=b.abs();//取绝对值
        if(a.compareTo(BigInteger.ZERO)==0||b.compareTo(BigInteger.ZERO)==0){
            return BigInteger.ZERO;
        }//存在一个为0 则结果为0
        else if(n1==1||n2==1) return sign.multiply(a).multiply(b);//存在一个为1,直接输出
        else{        
            
            int halfn=Math.max(n1, n2)/2;//假二分
            
            int n11=n1-halfn;//二分之后左边的位数
            int n22=n2-halfn;
            
            BigInteger temp1=BigInteger.valueOf(10).pow(halfn);//10^右边的位数
            BigInteger temp2=BigInteger.valueOf(10).pow(2*halfn);10^2倍的右边的位数参考公式
            
            BigInteger A=a.divide(temp1);  //第一个整数分割后的左边  
            BigInteger B=a.mod(temp1); //第一个整数分割后的右边  
            BigInteger C=b.divide(temp1); //第二个整数分割后的左边  
            BigInteger D=b.mod(temp1); //第二个整数分割后的右边  
            
            BigInteger ac=unsame(A,C,n11,n22);//递归求A+C
            BigInteger bd=unsame(B,D,halfn,halfn);//求B+D 参考公式
            //参考公式求取需要的参数
            BigInteger tm1=A.subtract(B);
            BigInteger tm2=D.subtract(C);
            int len1=tm1.abs().toString().length();
            int len2=tm2.abs().toString().length();
            
            BigInteger abcd=unsame(tm1,tm2,len1,len2).add(ac).add(bd);
            
            return sign.multiply(ac.multiply(temp2).add(abcd.multiply(temp1)).add(bd));                    
        }
    }
    public static void main(String[] args) {
        // TODO Auto-generated method stub
        Scanner sc=new Scanner(System.in);
        
        a=sc.nextBigInteger();
        b=sc.nextBigInteger();
        String sa=a.toString();
        String sb=b.toString();
        
            System.out.println(unsame(a,b,sa.length(),sb.length()));
        
    }

}

 

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值