浏览博客偶然看到https://blog.csdn.net/Colin_Qichao/article/details/81538327中给出的大数相乘算法,想到曾经有次面试时也被问到了该问题,于是仔细的研究了一下,并按照其思路写了一个两个大数相加的算法(这个问题也被面试官问到过....),现将算法贴出,与大家共享,如有问题,希望有人指出...
package cn.nrsc.algorithm.bigdata;
/**
*
* @author 孙川----两个大数进行相加
*
*/
public class BigDataPlus {
public static void main(String[] args) {
String num1 = "123456";
String num2 = "67891011";
String result = bigDataPlus(num1, num2);
System.out.println(result);
}
// 两个大数相加的算法
private static String bigDataPlus(String str1, String str2) {
int len1 = str1.length();
int len2 = str2.length();
// 两个大数相加,相加后位数的最大值----比两个数中较大的那个数的位数多1
int len = len1 > len2 ? len1 + 1 : len2 + 1;
// 存放相加后各个位上的和
int[] tmp = new int[len];
// 反转字符串,便于从低位到高位相加和最高位的进位导致和的位数增加
str1 = reverse(str1);
str2 = reverse(str2);
// 让两个字符串位数相同,不足的在后面补0,这样才能个位+个位,十位+十位,百位+百位+等等等
if (len1 < len2)
for (int i = len1; i < len2; i++)
str1 += "0";
else
for (int i = len2; i < len1; i++)
str2 += "0";
// 两个大数相加------个位+个位,十位+十位,百位+百位+等等等
// 字符转int 如将char类型的'9'转成int类型的9,只需 (int)'9' - (int)'0'
for (int j = 0; j < str1.length(); j++)
tmp[j] = (int) str1.charAt(j) - (int) '0' + (int) str2.charAt(j) - (int) '0';
// 进位问题
for (int j = 0; j < tmp.length; j++) {
// 判断是否需要进位
if (tmp[j] / 10 > 0)
// 更高位置进位
tmp[j + 1] += tmp[j] / 10;
// 取该位置对应数字
tmp[j] = tmp[j] % 10;
}
int m = 0;
for (int i = len - 1; i >= 0; i--) {
// 数组下标对应较高位置,即结果较高位数可能有多个0,不需要遍历应去除
if (tmp[i] > 0) {
m = i;
break;
}
}
StringBuilder sb = new StringBuilder();
// 从结果最高不为0位置开始遍历
for (int i = m; i >= 0; i--) {
sb.append(tmp[i]);
}
return sb.toString();
}
// 反转字符串
private static String reverse(String str) {
if (str == null || str.length() == 1)
return str;
return reverse(str.substring(1)) + str.charAt(0);
}
}
为了对比,也把大数相乘算法列在下面,来源于https://blog.csdn.net/Colin_Qichao/article/details/81538327
package cn.nrsc.algorithm.bigdata;
/**
* {大数相乘算法}
* @author 来源于https://blog.csdn.net/Colin_Qichao/article/details/81538327
*/
public class BigDataMultiply {
public static void main(String[] args) {
String str1 = "753656566859769";
String str2 = "9518598598486568654";
// 字符串反转,希望后面生成的数组位置0对应个位,位置1对应十位,位置2对应百位
str1 = reserve(str1);
str2 = reserve(str2);
int len1 = str1.length();
int len2 = str2.length();
int len = len1 + len2 + 3;
char[] chars1 = str1.toCharArray();
char[] chars2 = str2.toCharArray();
int a[] = new int[len1];
int b[] = new int[len2];
int c[] = new int[len];
for (int i = 0; i < len1; i++) {
a[i] = Integer.valueOf(String.valueOf(chars1[i]));
}
for (int i = 0; i < len2; i++) {
b[i] = Integer.valueOf(String.valueOf(chars2[i]));
}
String result = countMultiply(c, a, b, len, len1, len2);
System.out.println(result);
}
private static String countMultiply(int[] c, int[] a, int[] b, int len, int len1, int len2) {
for (int i = 0; i < len1; i++) {
for (int j = 0; j < len2; j++) {
// 核心代码:相乘结果各个位置上的值和乘数对应的位置有关联。
// 例如:结果个位上的数值只能由乘数个位上的数相乘取个位。
c[i + j] += a[i] * b[j];
}
}
for (int i = 0; i < len; i++) {
if (c[i] / 10 > 0) {// 判断是否需要进位
// 更高位置进位
c[i + 1] += c[i] / 10;
}
// 取该位置对应数字
c[i] = c[i] % 10;
}
int m = 0;
for (int i = len - 1; i >= 0; i--) {
// 数组下标对应较高位置,即结果较高位数可能有多个0,不需要遍历应去除
if (c[i] > 0) {
m = i;
break;
}
}
StringBuilder sb = new StringBuilder();
// 从结果最高不为0位置开始遍历
for (int i = m; i >= 0; i--) {
sb.append(c[i]);
}
return sb.toString();
}
private static String reserve(String str1) {
if (str1 == null || str1.length() == 1) {
return str1;
} else {
return reserve(str1.substring(1)) + str1.charAt(0);
}
}
}