算法:大整数相乘问题
给定两个数字作为字符串。这些数字可能非常大(可能不适合int long int int),或许相乘在计算机可能溢出了,所以任务是找到这两个数字的乘积。
1 Input : num1 = 4154 2 num2 = 51454 3 Output : 213739916 4 5 Input : num1 = 654154154151454545415415454 6 num2 = 63516561563156316545145146514654 7 Output : 41549622603955309777243716069997997007620439937711509062916
我们可以基于数学思想来分解两个大整数的相乘问题
从输入的第二个数字的最后一位开始乘以输入的第一个数字。然后,我们将第二个数字的倒数第二位数字与第一个数字相乘,依此类推。将所有这些乘法相加。在相加时,将第 i个乘法移位了。
以下解决方案中使用的方法是仅保留一个数组以获取结果。循环遍历所有数字的第一个和第二个数字,并将结果添加到适当的位置。其时间复杂度为 O(m * n),空间复杂度为 O(m+n),m 和 n 分别为两个大整数字符串的长度。
1 package algorithm; 2 3 /** 4 * 大整数相乘问题 5 */ 6 public class BIgIntMultiply { 7 /** 8 * 以字符串的形式输入两个大整数做乘法 9 * 10 * @param num1 整数1 11 * @param num2 整数2 12 * @return 13 */ 14 private static String multiply(String num1, String num2) { 15 int len1 = num1.length(); 16 int len2 = num2.length(); 17 if (len1 == 0 || len2 == 0) 18 return "0"; 19 20 /* 将结果数以相反的顺序保存在数组中 */ 21 int[] result = new int[len1 + len2]; 22 23 /* 以下两个索引用于查找结果中的位置(移位) */ 24 int i_n1 = 0; 25 int i_n2 = 0; 26 27 /* 在num1中从右到左 */ 28 for (int i = len1 - 1; i >= 0; i--) { 29 /* 临时保存需要进位的数 */ 30 int carry = 0; 31 int n1 = num1.charAt(i) - '0'; 32 33 /* 在num2中每个数字的乘法运算后向左移动位置 */ 34 i_n2 = 0; 35 36 /* 在num2中从右向左移动 */ 37 for (int j = len2 - 1; j >= 0; j--) { 38 /* 取第二个数字的当前数字 */ 39 int n2 = num2.charAt(j) - '0'; 40 41 /* 将当前数字与第一个数字相乘,然后将结果添加到先前存储的结果charAt当前位置 */ 42 int sum = n1 * n2 + result[i_n1 + i_n2] + carry; 43 44 /* 用于下一个迭代相加 */ 45 carry = sum / 10; 46 47 /* 存储结果 */ 48 result[i_n1 + i_n2] = sum % 10; 49 50 i_n2++; 51 } 52 53 /* 到最后还有进位值则移位放上去 */ 54 if (carry > 0) 55 result[i_n1 + i_n2] += carry; 56 57 /* 在num1中的每个数字重复后向左移动位置 */ 58 i_n1++; 59 } 60 61 /* 忽略最右边的0 */ 62 int i = result.length - 1; 63 while (i >= 0 && result[i] == 0) 64 i--; 65 66 /* 如果全部为'0', 表示num1或num2两者之一为'0'或者都为0 */ 67 if (i == -1) 68 return "0"; 69 70 /* 生成结果字符串 */ 71 StringBuilder s = new StringBuilder(); 72 while (i >= 0) { 73 s.append(result[i--]); 74 } 75 76 return s.toString(); 77 } 78 79 public static void main(String[] args) { 80 String str1 = "-1235421415454545454545454544"; 81 String str2 = "-1714546546546545454544548544544545"; 82 83 // String str1 = "1234"; 84 // String str2 = "5678"; 85 86 if (str1.charAt(0) == '-' && 87 str2.charAt(0) != '-') 88 { 89 str1 = str1.substring(1); 90 System.out.println("-"); 91 } 92 else if (str1.charAt(0) != '-' && 93 str2.charAt(0) == '-') 94 { 95 str2 = str2.substring(1); 96 System.out.println("-"); 97 } 98 else if (str1.charAt(0) == '-' && 99 str2.charAt(0) == '-') 100 { 101 str1 = str1.substring(1); 102 str2 = str2.substring(1); 103 } 104 /* 105 result: 2118187521397235888154583183918321221520083884298838480662480 106 copy from console: 2118187521397235888154583183918321221520083884298838480662480 107 */ 108 System.out.println(multiply(str1, str2)); 109 110 } 111 }