C++ 大数相加(简要版)
#include <algorithm>
#include <iterator>
class Solution {
public:
/**
* 计算两个数之和
* @param s string字符串 表示第一个整数
* @param t string字符串 表示第二个整数
* @return string字符串
*/
string solve(string s, string t)
{
// 处理空字符串的情况,如果 t 为空,则直接返回 s
if(t.size() == 0)
{
return s;
}
// 如果 s 为空,则直接返回 t
if(s.size() == 0)
{
return t;
}
// 将两个字符串反转,方便从低位到高位相加
reverse(s.begin(), s.end());
reverse(t.begin(), t.end());
// 确保 s 的长度不小于 t 的长度,方便处理进位
if(s.size() < t.size())
{
swap(s, t);
}
// 将 t 的长度扩展到与 s 相同,缺失的位补充为 0
while(t.size() < s.size())
{
t += '0';
}
// 获取 s 的长度,用于遍历
int size = s.size();
// 用于存储最终结果
string ret;
// 记录进位
int cnt = 0;
// 遍历每一位进行加法计算
for(int i = 0; i < size; i++)
{
// 计算当前位置的和,并加上上一次的进位
// 通过 s[i] 和 t[i] 的字符转换为整数进行加法
// '0' 是为了将字符转为数字,字符 '0' 对应整数值 0
// 计算的 tmp 是字符加法结果(可能带进位)
char tmp = s[i] + t[i] - '0' + cnt;
// 如果和大于 '9',则需要产生进位
if(tmp > '9')
{
tmp -= 10; // 将超过 9 的部分扣除,保留个位
cnt = 1; // 设置进位为 1
}
else
{
cnt = 0; // 不需要进位,cnt 设置为 0
}
// 将当前计算的字符加入到结果字符串中
ret += tmp;
}
// 如果遍历完所有位后仍有进位,则需要在结果末尾添加 1
if(cnt == 1)
{
ret += '1';
}
// 最后将结果字符串反转,得到正确的顺序
reverse(ret.begin(), ret.end());
// 返回最终计算的和
return ret;
}
};
详细中文注释解释:
-
空字符串处理:
-
如果
t
为空,直接返回s
。如果s
为空,直接返回t
。这是为了避免对空字符串进行无意义的加法。
-
-
字符串反转:
-
由于加法是从低位到高位进行的,因此我们首先将两个字符串反转,方便从低位开始相加。
-
-
调整字符串长度:
-
如果
s
比t
短,则交换它们的位置,保证s
总是较长的字符串。 -
然后将
t
的长度扩展到与s
相同,缺少的位补充为0
。这样做的目的是确保两个字符串的长度一致,方便逐位加法。
-
-
逐位加法:
-
通过一个循环,逐位计算两个字符串的和。每次加法会计算当前位的和,同时考虑上一个计算中的进位(
cnt
)。 -
如果当前位的和大于
9
,则产生进位。否则,不产生进位。
-
-
处理进位:
-
如果计算完所有位后仍然有进位(
cnt == 1
),则在结果字符串末尾加上1
。
-
-
反转结果:
-
最后,反转
ret
字符串,得到正确的加法结果。
-
举个例子:
假设 s = "123"
和 t = "987"
,我们将按以下步骤处理:
-
反转
s
和t
,得到"321"
和"789"
。 -
执行逐位加法:
3 + 7 = 10
,进位为 1;2 + 8 + 1 = 11
,进位为 1;1 + 9 + 1 = 11
,进位为 1。 -
结果是
"1110"
,然后再加上进位,得到最终的结果"1110"
。
时间复杂度:
-
时间复杂度是 O(n),其中
n
是两个字符串中较长字符串的长度。我们需要逐位遍历并进行加法操作。