大整数相乘递归 分治思想.docx
《大整数相乘递归 分治思想.docx》由会员分享,可在线阅读,更多相关《大整数相乘递归 分治思想.docx(9页珍藏版)》请在冰豆网上搜索。
大整数相乘递归分治思想
packagecom.liheng.algorithm;
importjava.util.Scanner;
importjava.util.regex.Matcher;
importjava.util.regex.Pattern
/**
*大整数乘法
*
*
*/
publicclassBigIntMultiply
{
//规模只要在这个范围内就可以直接计算了
privatefinalstaticintSIZE=4;
//此方法要保证入参len为X、Y的长度最大值
privatestaticStringbigIntMultiply(StringX,StringY,intlen)
{
//最终返回结果
StringSA_B,SD_C;
Stringstr="";
intflag=0;
//补齐X、Y,使之长度相同
X=formatNumber(X,len);
Y=formatNumber(Y,len);
//少于4位数,可直接计算
if(len<=SIZE)
{
return""+(Integer.parseInt(X)*Integer.parseInt(Y));
}
//将X、Y分别对半分成两部分
intlen1=len/2;
intlen2=len-len1;
StringA=X.substring(0,len1);
StringB=X.substring(len1);
StringC=Y.substring(0,len1);
StringD=Y.substring(len1);
//两字符串长度要相同
intlenM=Math.max(A.length(),B.length());
StringA1=formatNumber(A,lenM);
StringB1=formatNumber(B,lenM);
inta=Integer.parseInt(A1.substring(0,1));
intb=Integer.parseInt(B1.substring(0,1));
if(a>b)
{
SA_B=dudcting(A1,B1);
}
else
{
SA_B=dudcting(B1,A1);
flag++;
}
lenM=Math.max(A.length(),B.length());
StringC1=formatNumber(C,lenM);
StringD1=formatNumber(D,lenM);
intc=Integer.parseInt(C1.substring(0,1));
intd=Integer.parseInt(D1.substring(0,1));
if(d>c)
{
SD_C=dudcting(D1,C1);
}
else
{
SD_C=dudcting(C1,D1);
flag++;
}
lenM=Math.max(SA_B.length(),SD_C.length());
StringABDC="";
if(flag!
=1)
{
ABDC=bigIntMultiply(SA_B,SD_C,lenM);
}else
{
ABDC=bigIntMultiply(SA_B,SD_C,lenM);
}
StringAC=bigIntMultiply(A,C,len1);
StringBD=bigIntMultiply(B,D,len2);
//处理BD,得到原位及进位
String[]sBD=dealString(BD,len2);
//处理AD+BC的和
StringADBC=addition(AC,BD);
StringABCD="";
lenM=Math.max(ABDC.length(),ADBC.length());
if(flag==1)
{
StringABDC1=formatNumber(ABDC,lenM);
StringADBC1=formatNumber(ADBC,lenM);
inta1=Integer.parseInt(ABDC1.substring(0,1));
intb1=Integer.parseInt(ADBC1.substring(0,1));
ABCD=dudcting(ADBC1,ABDC1);
}
else
{
ABCD=addition(ABDC,ADBC);
}
flag=0;
//加上BD的进位
if(!
"0".equals(sBD[1]))
{
ABCD=addition(ABCD,sBD[1]);
}
//得到ADBC的进位
lenM=Math.max(len1,len2);
String[]sABCD=dealString(ABCD,lenM);
//AC加上ADBC的进位
AC=addition(AC,sABCD[1]);
//最终结果
str=AC+sABCD[0]+sBD[0];
returnstr;
}
//两个数字串按位加
privatestaticStringaddition(Stringad,Stringbc)
{
//返回的结果
Stringstr="";
//两字符串长度要相同
intlenM=Math.max(ad.length(),bc.length());
ad=formatNumber(ad,lenM);
bc=formatNumber(bc,lenM);
//按位加,进位存储在temp中
intflag=0;
//从后往前按位求和
for(inti=lenM-1;i>=0;i--)
{
intt=
flag+Integer.parseInt(ad.substring(i,i+1))
+Integer.parseInt(bc.substring(i,i+1));
//如果结果超过9,则进位当前位只保留个位数
if(t>9)
{
flag=1;
t=t-10;
}
else
{
flag=0;
}
//拼接结果字符串
str=""+t+str;
}
if(flag!
=0)
{
str=""+flag+str;
}
returnstr;
}
//两个数字串按位减
privatestaticStringdudcting(Stringad,Stringbc)
{
//返回的结果
Stringstr="";
//按位加,进位存储在temp中
intflag=0;
//从后往前按位求和
for(inti=ad.length()-1;i>=0;i--)
{
intt=flag+Integer.parseInt(ad.substring(i,i+1))-Integer.parseInt(bc.substring(i,i+1));
//如果结果超过9,则进位当前位只保留个位数
if(t<0)
{
flag=-1;
t=t+10;
}
else
{
flag=0;
}
//拼接结果字符串
str=""+t+str;
}
if(flag!
=0)
{
str=""+flag+str;
}
returnstr;
}
//处理数字串,分离出进位;
//String数组第一个为原位数字,第二个为进位
privatestaticString[]dealString(Stringac,intlen1)
{
String[]str={ac,"0"};
if(len1{
intt=ac.length()-len1;
str[0]=ac.substring(t);
str[1]=ac.substring(0,t);
}
else
{
//要保证结果的length与入参的len一致,少于则高位补0
Stringresult=str[0];
for(inti=result.length();i{
result="0"+result;
}
str[0]=result;
}
returnstr;
}
//乘数、被乘数位数对齐
privatestaticStringformatNumber(Stringx,intlen)
{
while(len>x.length())
{
x="0"+x;
}
returnx;
}
//测试桩
publicstaticvoidmain(String[]args)
{
//正则表达式:
不以0开头的数字串
Stringpat="^[1-9]\\d*$";
Patternp=Ppile(pat);
//获得乘数A
System.out.println("请输入乘数A(不以0开头的正整数):
");
Scannersc=newScanner(System.in);
StringA=sc.nextLine();
Matcherm=p.matcher(A);
if(!
m.matches())
{
System.out.println("数字不合法!
");
return;
}
//获得乘数B
System.out.println("请输入乘数B(不以0开头的正整数):
");
sc=newScanner(System.in);
StringB=sc.nextLine();
m=p.matcher(B);
if(!
m.matches())
{
System.out.println("数字不合法!
");
return;
}
System.out.println(A+"*"+B+"="
+bigIntMultiply(A,B,Math.max(A.length(),B.length())));
}
}