听说这是个频繁出现的算法题,在某某网站是的排行很靠前。面试腾讯的时候碰到了。

两个大数相加。
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"));    }