题目
给定两个字符串形式的非负整数 num1 和num2 ,计算它们的和。
提示:
- num1 和num2 的长度都小于 5100
- num1 和num2 都只包含数字 0-9
- num1 和num2 都不包含任何前导零
- 你不能使用任何內建 BigInteger 库, 也不能直接将输入的字符串转换为整数形式
解题思路
题目给定了 2 个字符串形式的非负整数,这个整数还有可能很大。
我们知道,Js 的 Number 类型 有个最大安全数的概念,即2的53次方,为 9007199254740992 。如果超过这个值,那么js会出现不精确的问题。这个值为 16 位。
所以单纯的用整型相加是行不通的(题目中也限定了不能直接将输入的字符串转换为整数形式)
那么我们该如何解决这个问题呢,来思考一下,我们最初学习加法的时候是怎么加的?
是不是两个数字列竖式,从最小位开始,逢十进一?那么这个问题也是同理,我们可以把两个数从最末位开始一位一位的往前加。
如果加到最后一位时结果大于等于10,直接在结果的前面加上一个1就好~~
具体代码实现如下:
let addStrings = (num1, num2) => {
// 结果字符串
let str = '';
// 表示是否需要进位 1-进位 0-不进位
let temp = 0;
// 两个字符串分别从尾部开始遍历相加,所以需要先获取字符串的末尾索引值
let i = num1.length - 1;
let j = num2.length - 1;
while (i >= 0 || j >= 0) {
let sum = temp; // 初始 temp 为 0,这里要加上 temp 是因为后续每两位相加 大于 10 时需要进一位,这里的 temp 就是作为进位的值。
if (i >= 0) {
sum += +num1[i--]; // i 用完之后要-1
}
if (j >= 0) {
sum += +num2[j--]; // 同理 j 用完之后也要 -1
}
temp = sum > 9 ? 1 : 0; // 两数之和大于 10 就进位,temp 设为 1,加到下一位的运算中去。
str = (sum % 10) + str; // 在字符串前面拼上这次运算出来的结果,对 10 取余就是个位
}
// 如果最后 temp 为 1 说明最后两个数字相加大于 10,所以在字符串前面补 1 就好。
return temp === 1 ? '1' + str : str;
}