public class DaShuXiangCheng {
//*********************** 【方法1】 Start **************************************
// 规模只要在这个范围内可以直接计算(整型数值满足)
private final static int SIZE = 4;
// 其中,len为X、Y的长度最大值
private static String bigIntMultiply(String X, String Y, int len) {
String str = "";
if (len <= SIZE) { // 少于4位数,可直接计算
return "" + (Integer.parseInt(X) * Integer.parseInt(Y));
}
if (X.length() != Y.length()) { // 长度不同,调用formatNumber方法,补齐X、Y,使之长度相同
X = formatNumber(X, len);
Y = formatNumber(Y, len);
}
// 将X、Y分别对半分成两部分
int len1 = len / 2;
int len2 = len - len1;
String A = X.substring(0, len1);
String B = X.substring(len1);
String C = Y.substring(0, len1);
String D = Y.substring(len1);
// 乘法法则,分块处理
int lenM = Math.max(len1, len2);
String AC = bigIntMultiply(A, C, len1);
String AD = bigIntMultiply(A, D, lenM);
String BC = bigIntMultiply(B, C, lenM);
String BD = bigIntMultiply(B, D, len2);
// 注意处理进位的方法,巧妙地运用了字符串的拼接方面
// 【1】 处理BD,得到原位及进位
String[] sBD = dealString(BD, len2);
// 【2】 处理AD + BC的和
String ADBC = add(AD, BC);
// 【3】 加上BD的进位
if (!"0".equals(sBD[1])) {
ADBC = add(ADBC, sBD[1]);
}
// 【4】 得到ADBC的进位
String[] sADBC = dealString(ADBC, lenM);
// 【5】 AC加上ADBC的进位
AC = add(AC, sADBC[1]);
// 【6】 最终结果
str = AC + sADBC[0] + sBD[0];
return str;
}
// 两个数字串按位加
private static String add(String ad, String bc) {
// 返回的结果
String str = "";
// 两字符串长度要相同
int lenM = Math.max(ad.length(), bc.length());
ad = formatNumber(ad, lenM);
bc = formatNumber(bc, lenM);
// 按位加,进位存储在flag中
int flag = 0;
// 按序从后往前按位求和
for (int i = lenM - 1; i >= 0; i--) {
int t = 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;
}
return str;
}
// 处理数字串,分离出进位,String数组第一个为原位数字,第二个为进位
private static String[] dealString(String ac, int lenn) {
String[] str = { ac, "0" };
if (lenn < ac.length()) {
int t = ac.length() - lenn;
str[0] = ac.substring(t);
str[1] = ac.substring(0, t);
// System.out.println("+++++++++");
// System.out.println(str[0]);
// System.out.println(str[1]);
// System.out.println(t);
} else {
// 保证结果length与lenn一致,少于则高位补0
String result = str[0];
for (int i = result.length(); i < lenn; i++) {
result = "0" + result;
}
str[0] = result;
}
return str;
}
// 格式化操作的数字字符串,高位补零
private static String formatNumber(String x, int len) {
while (len > x.length()) {
x = "0" + x;
}
return x;
}
//*********************** 【方法1】 End **************************************
//*********************** 【方法2】 Start **************************************
public static String multiply2(String num1, String num2){
//把字符串转换成char数组
char chars1[] = num1.toCharArray();
char chars2[] = num2.toCharArray();
//声明存放结果和两个乘积的容器
int result[] = new int[chars1.length + chars2.length];
int n1[] = new int[chars1.length];
int n2[] = new int[chars2.length];
//把char转换成int数组,为什么要减去一个'0'呢?因为要减去0的ascii码得到的就是实际的数字
for(int i = 0; i < chars1.length;i++)
n1[i] = chars1[i]-'0';
for(int i = 0; i < chars2.length;i++)
n2[i] = chars2[i]-'0';
//逐个相乘,因为你会发现。AB*CD = AC(BC+AD)BD , 然后进位。
for(int i =0 ; i < chars1.length; i++){
for(int j =0; j < chars2.length; j++){
result[i+j]+=n1[i]*n2[j];
}
}
//满10进位,从后往前满十进位
for(int i =result.length-1; i > 0 ;i--){
result[i-1] += result[i] / 10;
result[i] = result[i] % 10;
}
//转成string并返回
String resultStr = "";
for(int i = 0; i < result.length-1; i++){
resultStr+=""+result[i];
}
return resultStr;
}
//*********************** 【方法2】 End **************************************
public static void main(String[] args) {
//String x = "38202212122222222222222222222222221111111111111111111111111111111111111111111111111114444444";
//String y = "42204412121222222222222222222222225555555555555555555222222246666678921345643444657683512121";
//System.out.println("bigIntMultiply("+x+", "+y+", "+Math.max(x.length(), y.length())+")");
String x = "";
for(int i=1;i<100;i++){
x += i;
}
String y = "";
for(int i=99;i>0;i--){
y += i;
}
System.out.println("x = "+x);
System.out.println("y = "+y);
Long fun1_dateStart = new Date().getTime();
String result = bigIntMultiply(x, y, Math.max(x.length(), y.length()));
Long fun1_dateEnd = new Date().getTime();
System.out.println("方法1结果为 : "+result+"。 \r\n 用时 : "+(fun1_dateEnd - fun1_dateStart));
//System.out.println(x+" * "+y+" = "+result);
Long fun2_dateStart = new Date().getTime();
String result2 = multiply2(x, y);
Long fun2_dateEnd = new Date().getTime();
System.out.println("方法2结果为 : "+result2+"。 \r\n 用时 : "+(fun2_dateEnd - fun2_dateStart));
//System.out.println("multiply2("+x+", "+y+") = "+result2);
}
}
JAVA大数相乘实现方法
最新推荐文章于 2024-07-14 03:26:01 发布