您的位置:首页 > 编程语言 > Java开发

大整数乘法

2015-03-30 14:26 169 查看
1. 采用递归分治法

ab*cd=ac(bc+ad)bd

public String BigMutiple(String t1, String t2) {
// 临界条件
if (t1.length() <= size && t2.length() <= size) {
return String.valueOf(Integer.parseInt(t1) * Integer.parseInt(t2));
}
// 预处理 make sure:t1.length = t2.length
if (t1.length() != t2.length()) {
boolean taglenth = t1.length() > t2.length() ? true : false;
int distance = Math.abs(t1.length() - t2.length());
if (taglenth) {
t2 = belonger(t2, distance);
} else {
t1 = belonger(t1, distance);
}
}
// ensureLength(t1, t2);
String[] AB = numSplite(t1);
String[] CD = numSplite(t2);
String a = AB[0];
String b = AB[1];
String c = CD[0];
String d = CD[1];
int saveprefix = a.length();
int savesuffix = b.length();
assert (a.length() == c.length());
assert (c.length() == d.length());
String ac = BigMutiple(a, c);
String ad = BigMutiple(a, d);
String bc = BigMutiple(b, c);
String bd = BigMutiple(b, d);

return intergration(ac, ad, bc, bd, saveprefix, savesuffix);
}

private String belonger(String t1, int length) {
StringBuilder sb = new StringBuilder("");
for (int i = 0; i < length; i++) {
sb.append("0");
}
return sb.toString() + t1;
//如果使用字符数组,return charArray.toString(),返回的是对象名+hash地址一类的东西。
}

private String intergration(String ac, String ad, String bc, String bd, int saveprefix, int savesuffix) {
String result = "";
String[] endStrings = resultSplite(bd, savesuffix);
assert (endStrings.length == 2);
String endoverflow = endStrings[0];
int savemiddle = (saveprefix >= savesuffix) ? saveprefix : savesuffix;
// String[] middleStrings = resultSplite(Bigadd(ad, bc, endoverflow), savemiddle);
String[] middleStrings = resultSplite(MutileAdd(ad, bc, endoverflow), savemiddle);
String middleroverflow = middleStrings[0];
String[] startStrings = resultSplite(Bigadd(ac, middleroverflow, "0"), saveprefix);
result = startStrings[0] + startStrings[1] + middleStrings[1] + endStrings[1];
return result;
}

private String Bigadd(String ad, String bc, String endoverflow) {
// 将ad,bc,endoverflow相加
String resultString = "";
String result = "";
if (ad.length() != bc.length()) {
boolean taglenth = ad.length() > bc.length() ? true : false;
int distance = Math.abs(ad.length() - bc.length());
if (taglenth) {
bc = belonger(bc, distance);
} else {
ad = belonger(ad, distance);
}
}
assert (ad.length() == bc.length());
int overtag = 0;
for (int i = ad.length() - 1; i >= 0; i--) {
int tempresult = (ad.charAt(i) - '0') + (bc.charAt(i) - '0') + overtag;
if (tempresult < 10) {//bug
resultString = (tempresult + "")+resultString;
overtag = 0;//bug
} else {
resultString = ((tempresult - 10) + "")+resultString;
overtag = 1;
}
}
//bug:最高为进位
if (overtag!=0) {
resultString=overtag+""+resultString;
}
if (resultString.length() != endoverflow.length()) {
boolean taglenth = resultString.length() > endoverflow.length() ? true : false;
int distance = Math.abs(resultString.length() - endoverflow.length());
if (taglenth) {
endoverflow = belonger(endoverflow, distance);
} else {
resultString = belonger(resultString, distance);
}
}
//标志位的置位和恢复
overtag = 0;
for (int i = resultString.length() - 1; i >= 0; i--) {
int tempresult = (resultString.charAt(i) - '0') + (endoverflow.charAt(i) - '0') + overtag;
if (tempresult < 10) {//bug
result = (tempresult + "")+result ;
overtag = 0;//bug
} else {
result =((tempresult - 10) + "")+ result;
overtag = 1;
}
}
//bug:最高位进位
if (overtag!=0) {
result=overtag+""+result;
}
return result;
}

private String MutileAdd(String anum,String bnum,String overbit){
//make sure length is the same
//maxlenth这个函数,返回值的含义预想的跟实际实现时是不同的。关键在于当时没有明确的确定。
//maxlenth这个函数,返回最大的字符串的长度
int maxlenth = maxlenth(anum,bnum,overbit);
anum = belonger(anum, maxlenth-anum.length());
bnum = belonger(bnum, maxlenth-bnum.length());
overbit = belonger(overbit, maxlenth-overbit.length());
assert(anum.length()==bnum.length());
assert(bnum.length()==overbit.length());
String resultString = "";
int overflag = 0;
for (int i = maxlenth-1; i>=0; i--) {
//这里是3个数相加,进位有三种可能:0,1,2 所以用boolean不能表示
int temp = (anum.charAt(i)-'0')+(bnum.charAt(i)-'0')+(overbit.charAt(i)-'0')+overflag;
overflag = temp/10;
temp = temp-overflag*10;
resultString = (temp+"")+resultString;
}
if (overflag!=0) {
resultString = overflag+resultString;
}
return resultString;
}

private int maxlenth(String anum, String bnum, String overbit) {
// TODO Auto-generated method stub
if (anum.length()>=bnum.length()) {
if (anum.length()>=overbit.length()) {
return anum.length();
} else {
return overbit.length();
}
} else {
if (bnum.length()>=overbit.length()) {
return bnum.length();
} else {
return overbit.length();
}
}
}

private String[] resultSplite(String bd, int savesuffix) {
// assert (bd.length() >= savesuffix);
if (bd.length()==savesuffix) {
return new String[]{"0",bd};
}else if (bd.length()>savesuffix) {
//bug :在截取时,截取位置容易出错
return new String[] { bd.substring(0, (bd.length()-savesuffix)), bd.substring(bd.length()-savesuffix) };
}else{
bd =belonger(bd, savesuffix-bd.length());
return new String[]{"0",bd};
}

}

private String[] numSplite(String t1) {
int n = t1.length() / 2;
String[] parts = { t1.substring(0, n), t1.substring(n) };
return parts;
}
2.不考虑进位的列式乘法

原理:

 123
× 12
 246
123 
1476
public String twoMulti(String aString,String bString){
// if (aString.length()<=size&&bString.length()<=size) {
// return String.valueOf(Integer.parseInt(aString)*Integer.parseInt(bString));
// }
//初始化为0
int []result = new int[resultlenth];
for (int i = aString.length()-1; i >=0; i--) {
for (int j = bString.length()-1; j >=0; j--) {
int temp = (aString.charAt(i)-'0')*(bString.charAt(j)-'0');
int offset = aString.length()-1-i+bString.length()-1-j;
result[offset]=result[offset]+temp;
}
}
//对结果数组进行处理
for (int i = 0; i < result.length-1; i++) {
int save = result[i]%10;
int overflow = result[i]/10;
result[i]=save;
result[i+1]+=overflow;
}
StringBuilder sBuilder = new StringBuilder("");
boolean tag = true;
for (int i = resultlenth-1; i >=0; i--) {
if (result[i]==0&&tag) {
continue;
// i--;
}else {
tag=false;
sBuilder.append(result[i]);
}
}
return sBuilder.toString();
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  java 递归 大数乘法