目录
1.大数加法
就是模拟就好了,模拟加法计算的过程:
class Solution {
public:
int tmp, m, n;
string solve(string s, string t) {
string ret;
m = s.size() - 1;
n = t.size() - 1;
tmp = 0;
while (m >= 0 || n >= 0 || tmp) {
if (m >= 0) {
tmp += s[m] - '0';
m--;
}
if (n >= 0) {
tmp += t[n] - '0';
n--;
}
ret += tmp % 10 + '0';
tmp /= 10;
}
reverse(ret.begin(), ret.end());
return ret;
}
};
最后别忘记将ret逆置一下,因为是从尾开始存入的。
2.链表相加
因为要模拟加法运算,链表又是单向的,所以需要将其逆转,再进行加法模拟。
即(逆序 + 高精度加法)
注意:最后的结果是倒过来的,所以需要写逆置再返回。
详细代码:
class Solution {
public:
ListNode* Reverse(ListNode* head)
{
ListNode* newhead = new ListNode(0);
ListNode* cur = head;
while(cur)
{
ListNode* next = cur->next;
cur->next = newhead->next;
newhead->next = cur;
cur = next;
}
cur = newhead->next;
delete newhead;
newhead = nullptr;
return cur;
}
ListNode* addInList(ListNode* head1, ListNode* head2) {
head1 = Reverse(head1);
head2 = Reverse(head2);
ListNode* reth = new ListNode(0);
ListNode* prev = reth;
int t = 0;
ListNode* cur1 = head1, *cur2 = head2;
while(cur1 || cur2 || t)
{
if(cur1)
{
t += cur1->val;
cur1 = cur1->next;
}
if(cur2)
{
t += cur2->val;
cur2 = cur2->next;
}
prev = prev->next = new ListNode(t % 10);
t /= 10;
}
ListNode* cur = reth->next;
delete reth;
reth = nullptr;
return Reverse(cur);
}
};
3.大数乘法
实际上就是模拟乘法运算。
根据上述分析可以得到,其在一个点的和的下标正好为s和t的下标相加。(因此将每个string反过来更好分析和计算【因为下标的缘故】)
最后将得到的和进行高精度加法就可得结果(返回时记得除去前导零与逆置)
这道题要处理的细节还是蛮多的,要多加分析特殊情况
详细代码:
class Solution {
public:
string solve(string s, string t) {
int m = s.size();
int n = t.size();
vector<int> tmp(m + n);
string ret;
reverse(s.begin(), s.end());
reverse(t.begin(), t.end());
// 用vector存储每个位置的和
for(int i = 0; i < m; ++i)
{
for(int j = 0; j < n; ++j)
{
tmp[i + j] += (s[i] - '0') * (t[j] - '0');
}
}
// 遍历vector且高精度相加
int tt = 0;
for(int i : tmp)
{
int sum = i + tt;
ret += sum % 10 + '0';
tt = sum / 10;
}
// 加上剩余的进位
while(tt)
{
ret += tt % 10 + '0';
tt /= 10;
}
// 出去前导0
while(ret.size() > 1 && ret.back() == '0')
ret.pop_back();
// 逆置返回
reverse(ret.begin(), ret.end());
return ret;
}
};