听说这是个频繁出现的算法题,在某某网站是的排行很靠前。面试腾讯的时候碰到了。
两个大数相加。
1、是整数;
2、两个数无限大,long都装不下;
3、不能用BigInteger;
4、不能用任何包装类提供的运算方法;
5、两个数都是以字符串的方式提供。
两个字符串的数字,怎么相加?
其实也简单,核心点考的是ASCII码和相加进位的问题。
如果用BigDecimal:
private static void add2Sum(String s1, String s2) { System.out.println("-----------"); BigDecimal b1 = new BigDecimal(s1); BigDecimal b2 = new BigDecimal(s2) System.out.println("BigDecimal:"+b1.add(b2)); }
公司不是考察这个用法的,是想让你自己写一个加法计算过程:
该思路是:
1.反转两个字符串,便于从低位到高位相加和最高位的进位导致和的位数增加;
2.对齐两个字符串,即短字符串的高位用‘0’补齐,便于后面的相加;
3.从头遍历,把两个正整数的每一位都相加,并加上进位;
4.最高位有进位则补上进位;
5.逆序输出;
在这里需要说明一点的是,string 类是没有reverse()方法的,所以,为了便利,在这里我们用了StringBuffer,可以使用它自带的reverse()方法,很方便。
public static void main(String[] args) { Scanner sc = new Scanner(System.in); String s1 = sc.nextLine(); String s2 = sc.nextLine(); //反转字符串 String n1 = new StringBuffer(s1).reverse().toString(); String n2 = new StringBuffer(s2).reverse().toString(); int l1 = n1.length(); int l2 = n2.length(); int maxL = l1>l2?l1:l2; //补齐0 if (l1 < l2) { for (int i = l1; i < l2; i++) { n1 += "0"; } }else { for (int i = l2; i < l1; i++) { n2 += "0"; } } //System.out.println(n1);//test //System.out.println(n2);//test StringBuffer res = new StringBuffer();//存放的结果 int c = 0;//进位 for (int i = 0; i < maxL; i++) { int nSum = Integer.parseInt(n1.charAt(i) + "") + Integer.parseInt(n2.charAt(i) + "") + c; int ap = nSum%10; res.append(ap); c = nSum/10; } if (c>0) { res.append(c); } //System.out.println(res);//test System.out.println(res.reverse()); }
public static void main(String[] args) { String str1 = "123459"; String str2 = "123"; System.out.println(add(str1, str2));//123582} private static String add(String str1, String str2) { //任何一个字符串为null或空字符串,都不需要相加了 if (str1 == null || "".equals(str1)) { return str2; } if (str2 == null || "".equals(str2)) { return str1; } int maxLength = Math.max(str1.length(), str2.length()); //定义一个存贮结果的字符串,长度要比最大长度字符串还长一位,用于存储可能出现的进位 StringBuffer result = new StringBuffer(maxLength + 1); //翻转两个字符串 str1 = new StringBuffer(str1).reverse().toString(); str2 = new StringBuffer(str2).reverse().toString(); //反转后的结果分别为: //954321 //321 int minLength = Math.min(str1.length(), str2.length()); //进位 int carry = 0; //当前位上的数值 int currentNum = 0; //循环变量 int i = 0; for (; i < minLength; i++) { //分别获取两个字符对应的字面数值,然后相加,再加上进位 currentNum = str1.charAt(i) + str2.charAt(i) - 2 * '0' + carry; //获取进位 carry = currentNum / 10; //处理当前位的最终值 currentNum %= 10; //保存当前位的值到最终的字符缓冲区中 result.append(String.valueOf(currentNum)); } if (str1.length() < str2.length()) { //选择 str1 = str2; } for (; i < str1.length(); i++) { //分别获取两个字符对应的字面数值,然后相加,再加上进位 currentNum = str1.charAt(i) - '0' + carry; //获取进位 carry = currentNum / 10; //处理当前位的最终值 currentNum %= 10; //保存当前位的值到最终的字符缓冲区中 result.append(String.valueOf(currentNum)); } //处理最后一个的进位(当循环结束后,是不是还可能会有一个进位) if (carry > 0) { result.append(String.valueOf(carry)); } //最后翻转恢复字符串,再返回 return result.reverse().toString();}
/**
* 大整数求和
* @param bigNumberA 大整数A
* @param bigNumberB 大整数B
*/
public static String bigNumberSum(String bigNumberA, String bigNumberB) {
//1.把两个大整数用数组逆序存储,数组长度等于较大整数位数+1
int maxLength = bigNumberA.length() > bigNumberB.length() ? bigNumberA.length() : bigNumberB.length();
int[] arrayA = new int[maxLength+1];
for(int i=0; i< bigNumberA.length(); i++){
arrayA[i] = bigNumberA.charAt(bigNumberA.length()-1-i) - '0';//“ - '0'”是将String型转化为int型
}
int[] arrayB = new int[maxLength+1];
for(int i=0; i< bigNumberB.length(); i++){
arrayB[i] = bigNumberB.charAt(bigNumberB.length()-1-i) - '0';
}
//2.构建result数组,数组长度等于较大整数位数+1
int[] result = new int[maxLength+1];
//3.遍历数组,按位相加
for(int i=0; i<result.length; i++){
int temp = result[i]; //加上前一位的进位
temp += arrayA[i];
temp += arrayB[i];
//判断是否进位
if(temp >= 10){
temp = temp-10; //有进位的话将temp化为一位数
result[i+1] = 1; //将进位1存储到结果数组的下一位
}
result[i] = temp; //将1位数存储到结果数组对应位
}
//4.把result数组再次逆序并转成String
StringBuilder sb = new StringBuilder();
//用于标记是否找到大整数的最高有效位
boolean findFirst = false;
for (int i = result.length - 1; i >= 0; i--) {//从后往前
if(!findFirst){
if(result[i] == 0){ //用于跳过结果数组末尾的0
continue;
}
findFirst = true;
}
sb.append(result[i]);
}
return sb.toString();
}
public static void main(String[] args) {
System.out.println(bigNumberSum("426709752318", "95481253129"));
}