题目链接: https://leetcode.cn/problems/add-strings/
题目如下:

解题过程:
注意数据都是字符的形式。
思路:两个字符串形式的非负整数实现大数运算,从后(end1、end2,有小于0的情况,所以都是整型)往前计算,计算出一位就插入(谨慎使用insert,因为要挪动数据,时间复杂度不好。优化:尾插 + 逆置)到新建立的字符串中,都计算完了就将这个字符串返回,为了防止每次插入计算结果的数据的过程中有异地扩容的可能,用reserve提前将空间开好,空间大小是两个字符串的有效数据个数的最大值 + 1(加1是因为有向最大位进位的可能性)。计算过程中,两个字符串可能一长一短,长短都结束才能结束(循环判断结束条件),短的结束不能结束。两个字符串中只要有一个end >= 0就进入循环,取end对应的值进行计算可能end此时已经越界(end < 0),所以要写个三目操作符,int val = end >= 0 ? num[end--] : 0;。end1 < 0 && end2 < 0跳出循环,会有向最高位进位的可能性,所以要将进位的1追加到字符串中,最后进行逆置。
给下标起名字要有对应性,num1对应end1,num1对应end2。
大数相加。
大数运算主要是+,其实还包括减乘除。
计算机中用4个字节、最多也只是用8个字节去存储,表示的整型(/float/double)位数是有限的。4个字节,2^32就是42亿9000万,十进制的角度就是10位数,若是50多亿,4个字节的整型就表示不下,8个字节能表示的大一点,但是10进制下,肯定就存储不下100位的整数。那么这时需要我们模拟去运算,整数用字符串存储,每一个整数都是字符的形式,实现大数运算。
不能把短的计算结束,就把剩余的长的直接落下来,有极端的测试用例:999999999999 + 1 != 999999999990
若是短的结束了,再访问会有越界的可能,所以用三目操作符。
后置–,返回的–前的值,取完值再–。
用reserve把需要的空间一次性开好,减少异地扩容,不消耗内存。
max函数会返回两个数中的最大值。

完整代码:
class Solution {
public:
string addStrings(string num1, string num2) {
string str;
//reserve
str.reserve(max(num1.size(), num2.size()) + 1);
int end1 = num1.size() - 1, end2 = num2.size() - 1;
int next = 0;// 进位
while (end1 >= 0 || end2 >= 0)
{
int val1 = end1 >= 0 ? num1[end1--] - '0' : 0;//注意数据是字符的形式
int val2 = end2 >= 0 ? num2[end2--] - '0' : 0;//注意数据是字符的形式
int ret = val1 + val2 + next;
next = ret / 10;
ret = ret % 10;
//尾插
str += (ret + '0');
}
if (next == 1)
{
str += '1';
}
//逆置
reverse(str.begin(), str.end());
return str;
}
};

2783

被折叠的 条评论
为什么被折叠?



