兩個大數相加和兩個大數相乘-------java版(曾經面試遇到過)
阿新 • • 發佈:2018-11-26
瀏覽部落格偶然看到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); } } }