问题描述
求两个不超过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()));
}
}