目录
1、大数加法
1.1 题目
1.2 思路
1.3 代码实现
2、链表相加(二)
2.1 题目
2.2 思路
2.3 代码实现
3、大数乘法
3.1 题目
3.2 思路
3.3 代码实现
1、大数加法
1.1 题目
1.2 思路
这道题可以模拟列竖式相加解答, 将每一位都转换为数字求和,最后在转回字符串返回。
先求得两个字符串的长度,采用预处理一位一位的相加,定义一个变量表示进位
最后,我们算完后是逆序的结果,应该输出正序的结果,所以用reverse逆置一下
1.3 代码实现
class Solution {
public:
string solve(string s, string t)
{
string ret;
int i = s.size() - 1,j = t.size() - 1;
int tmp = 0;//表示进位
while(i >= 0 && j >= 0 || tmp > 0) //模拟加法
{
if(i >= 0)
tmp += s[i--] - '0';
if(j >= 0)
tmp += t[j--] - '0';
ret += tmp % 10 + '0';
tmp /= 10;
}
reverse(ret.begin(),ret.end());
return ret;
}
};
2、链表相加(二)
2.1 题目
2.2 思路
这题和上题类似,只不过是用链表完成加法,用高精度加法,先把原来的链表逆序,在使用高精度加法
创建一个虚拟头结点,就可以不用考虑节点为空的情况了,因为要链表都需要逆序,所以可以先封装一个逆序函数,模拟头插,循环插入,直到链表逆序,然后循环实现个位上的加法
2.3 代码实现
记得定义一个next记录原链表的下一个节点,否则cur不能回去原链表继续遍历
class Solution
{
public:
ListNode* reverse(ListNode* head)
{
ListNode* newhaead = new ListNode(0);
ListNode* cur = head;
while(cur)
{
ListNode* next = cur->next;
cur->next = newhaead->next;
newhaead->next = cur;
cur = next;
}
cur = newhaead->next;
delete[] newhaead;
return cur;
}
ListNode* addInList(ListNode* head1, ListNode* head2)
{ //逆序
head1 = reverse(head1);
head2 = reverse(head2);
int t = 0;//标记进位
ListNode* cur1 = head1,*cur2 = head2;
ListNode*ret = new ListNode(0);
ListNode* prev = ret;
while(cur1 ||cur2 || t)//大数加法
{
if(cur1)
{
t += cur1->val;
cur1 = cur1->next;
}
if(cur2)
{
t += cur2->val;
cur2 = cur2->next;
}
prev->next = new ListNode(t%10);
prev = prev->next;
t /= 10;
}
prev = ret->next;
ret->next = nullptr;
delete[] ret;
prev = reverse(prev);
return prev;
}
};
3、大数乘法
3.1 题目
3.2 思路
这道题也和第一题类似,不过这道题是实现字符串乘法,化繁为简,把乘数换成加法运算
无进位相乘
用无进位相乘,下标映射会非常舒服
3.3 代码实现
注意进位未处理和先导0
class Solution {
public:
string solve(string s, string t)
{
reverse(s.begin(),s.end());
reverse(t.begin(),t.end());
int m = s.size(),n = t.size();
vector<int> tmp(m+n);
// 无进位相乘相加,先固定s中一个数
for(int i = 0;i < m;i++)
{ //然后依次与t中的数相乘
for(int j = 0;j < n;j++)
{
tmp[i+j] += (s[i]-'0') * (t[j]-'0');
}
}
//处理进位
int k = 0;
string ret;
for(auto x : tmp)
{
k += x;
ret += k % 10 +'0';
k /= 10;
}
while(k)
{ //防止还有进位未处理
ret += k%10 +'0';
k /= 10;
}
while(ret.size() > 1 && ret.back()=='0')
ret.pop_back(); //处理前导0
reverse(ret.begin(),ret.end());
return ret;
}
};
本篇完,下篇见!