给定两个字符串形式的非负整数 num1
和num2
,计算它们的和。
注意:
num1
和num2
的长度都小于 5100.num1
和num2
都只包含数字0-9
.num1
和num2
都不包含任何前导零。- 你不能使用任何內建 BigInteger 库, 也不能直接将输入的字符串转换为整数形式。
分析:
由于数长度小于5100,我们不能将其转化为整数,然后再利用整数的加法来进行运算,因为这样做,就算是long类型的数也远远不够表示这两个数,所以我们需要从另外一个角度来思考。既然我们不能将其转化为整数,那我们何不从加法的起源开始思考。让我们想想我们在小学学习的加法运算是怎么进行的,是不是将两个数列一个竖式,让两个数的个位对个位,十位对十位。。。然后从个位开始相加,若两数的和大于10,则向十位进一,然后十位对应的数进行相加,再加上个位传来的进位,若大于10,向百位进一,以此类推直到得到两数之和的结果。既然我们知道了加法的执行过程,让我们也可以对两个数超级大的进行相加执行这样的操作,这样每次只操作一位数,就不会存在之前的整数类型存储不下数据的情况了。既然思路已经理清了,我们就可以动手实现我们的算法了。
代码实现:
public String addStrings(String num1, String num2) {
int length1 = num1.length(); //获取两个数的长度
int length2 = num2.length();
StringBuilder stringBuilder1,stringBuilder2;
//比较两个数的长度,将长度较大的放入到stringBuilder1,较小的放入到stringBuilder2
if(length1>length2){
stringBuilder1= new StringBuilder(num1);
stringBuilder2 = new StringBuilder(num2);
}else {
stringBuilder1= new StringBuilder(num2);
stringBuilder2 = new StringBuilder(num1);
length2 = length1; //交换length1与length2
length1 = num2.length();
}
StringBuilder result = new StringBuilder(); //定义变量result来存储结果
stringBuilder1.reverse(); //调用StringBuilder类的reverse方法将整数反转
stringBuilder2.reverse();
int carry = 0; //进位
for(int i=0;i<length2;i++){ //从两数的个位开始,循坏length2次,即两数中长度最短的次数
//对应位上的数进行相加,再加上后面往前面的进位
//通过相应位的字符减去字符'0'得到相应的整数的大小
int val = stringBuilder1.charAt(i) -'0' + stringBuilder2.charAt(i)- '0' + carry;
result.append(val%10); //自身留下对应位相加的结果的个位
carry = val/10; //向前面的进位大小
}
for (int i = length2; i < length1; i++) { //从两数中长度较长的数"多出"的那部分加上后面传来的进位
int val = stringBuilder1.charAt(i) - '0' + carry;
result.append(val%10);
carry = val/10;
}
if(carry!=0){ //若进位不为0,说明后面还有进位,即两数相加之和的最高位
result.append(carry);
}
return result.reverse().toString(); //返回结果
}
另一种更简洁的实现方式:
public static String addStrings2(String num1, String num2) {
StringBuilder sb = new StringBuilder(); //定义StringBuilder来存储结果
int carry = 0; //进位
for (int i = num1.length() - 1, j = num2.length() - 1; i >= 0 || j >= 0
|| carry > 0; i--, j--) { //从每个数的个位开始相加。当i或j有一个大于0,或进位不为0时继续相加过程
int x = i < 0 ? 0 : num1.charAt(i) - '0'; //获取两数
int y = j < 0 ? 0 : num2.charAt(j) - '0';
int sum = x + y + carry; //对应位相加,并加上进位
sb.append(sum % 10); //对应位留下相加结果的个位
carry = sum / 10; //向前进位
}
return sb.reverse().toString(); //返回结果
}