大数加法
最核心的代码就是
while (i >= 0 || j >= 0 || carry > 0)
只要有一个字符串没有遍历完或者还有进位的话就继续循环
int digitS = (i >= 0) ? s[i] - '0' : 0;
相当于将s、t与最终的结果相差的位补零。
首先是s、t两者对齐,短的左边补零,
如果有进位的话,两者都接着补零。
之所以补零,是因为方便计算。
string solve(string s, string t) {
// write code here
string result;
int carry = 0; // 初始化进位为0
int i = s.size() - 1;
int j = t.size() - 1;
// 从低位到高位遍历两个字符串
while (i >= 0 || j >= 0 || carry > 0) {
int digitS = (i >= 0) ? s[i] - '0' : 0; // 如果s还有剩余,则取当前位
int digitT = (j >= 0) ? t[j] - '0' : 0; // 如果t还有剩余,则取当前位
// 计算当前位的和
int sum = digitS + digitT + carry;
// 更新进位
carry = sum / 10;
// 当前位的结果
result.push_back((sum % 10) + '0');
i--;
j--;
}
// 结果字符串是反向的,需要反转
reverse(result.begin(), result.end());
return result;
}
大数乘法
模拟手写计算式计算
string solve(string s, string t) {
auto m = s.size();
auto n = t.size();
vector<int> ans(m + n, 0);
for (int i = m - 1; i >= 0; i--) {
for (int j = n - 1; j >= 0; j--) {
auto mul = (s[i] - '0') * (t[j] - '0');
//pos1所代表的位是进位
auto pos1 = i + j;
auto pos2 = i + j + 1;
//见上图
int sum = mul + ans[pos2];
ans[pos1] += sum / 10;
ans[pos2] = sum % 10;
}
}
string res;
for (auto num : ans) {
if (!(res.empty() && num == 0)) {
res.push_back(num + '0');
}
}
return res == "" ? "0" : res;
}