近期看的算法比較雜,在博客上簡單記錄一下吧。大數相乘貌似在不少公司的面試中都有問過。面試
問題描述:算法
輸入兩個整數,要求輸出這兩個數的乘積。輸入的數字可能超過計算機內整形數據的存儲範圍。spa
乘數A和B分別存放在字符串裏,輸出結果也存放在字符串中。code
問題分析:blog
首先,考慮相似0000000123456789這樣數字輸入,爲了不沒必要要的計算,能夠對輸入字符串進行預處理preProcess,把前綴爲0的字符串簡化爲從第一個不爲零的數字開始的字符串。ip
其次,考慮輸出字符串的長度,假設A的長度爲a,B的長度爲b,則二者相乘的長度爲a + b - 1或者a + b。字符串
第三,注意char和int之間的相互轉化,char c轉int a的方法:a = c - '0'或 a = c - 48,int a轉char c的方法:c = (char) (a + 48)博客
而後,每次用一個數的一位與另外一個數從低至高依次相乘,並與結果上的該位相加,動態更新結果。這個過程須要有addFlag和multiFlag來記錄上次運算的加法進位和乘法進位。class
最後,一樣使用preProcess將結果最高位的0去掉。test
public class Multiple { public String multiple(String A, String B) { String A1 = preProcess(A); String B1 = preProcess(B); char[] c1 = A1.toCharArray(); char[] c2 = B1.toCharArray(); char[] rst = new char[c1.length + c2.length]; for (int i = 0; i < rst.length; i++) { rst[i] = '0'; } reverse(c1, 0, c1.length - 1); reverse(c2, 0, c2.length - 1); for (int i = 0; i < c1.length; i++) { int addFlag = 0; int multiFlag = 0; for (int j = 0; j < c2.length; j++) { int temp1 = (c1[i] - 48) * (c2[j] - 48) + multiFlag; multiFlag = temp1 / 10; temp1 = temp1 % 10; int temp2 = rst[i + j] - 48 + temp1 + addFlag; addFlag = temp2 / 10; rst[i + j] = (char) (temp2 % 10 + 48); } rst[i + c2.length] = (char) (addFlag + multiFlag + 48); } reverse(rst, 0, rst.length - 1); return preProcess(new String(rst)); } public void reverse(char[] c, int start, int end) { while (start < end) { char temp = c[start]; c[start] = c[end]; c[end] = temp; start++; end--; } } public String preProcess(String s) { char[] c = s.toCharArray(); int i = 0; while (i < c.length) { if (c[i] == '0') { i++; continue; } else { break; } } if (i == c.length) { return new String("0"); } return new String(c, i, c.length - i); } }
test case試過了「0000」*「00」,「999999」*「99」,「0011」*「01」這樣的邊界case,都沒有問題。
這裏的乘法默認是非負數相乘,若爲負數相乘,只須要預先判斷第一位,最後在結果加上相應符號便可。