Welcome~
加法运算是一种模板式的东西.掌握了这个模板,任何形式的加法运算题目都能一气呵成~
首先,我们一起来回顾一下竖式相加的过程:
大概是这样一个过程:
末尾相加.8+5=15
这个结果15的末位5留下来,就是结果的末位
15的十位1作为进位
重复各位的操作.十位相加1+9=10
加上进位1.10+1=11
最终结果把11和5连接即可.115.
通过以上分析.两个正整数相加,每次都是对应位上的数字以及上一位的进位相加得到结果carry,(第一次末尾相加相当于carry=0),carry的个位是最终和的对应位,carry的十位作为进位参与高一位的运算.
根据这个思路,我们可以解决下面几题:
字符串相加(力扣415)
给定两个字符串形式的非负整数 num1
和num2
,计算它们的和。
注意:
num1
和num2
的长度都小于 5100.num1
和num2
都只包含数字0-9
.num1
和num2
都不包含任何前导零。你不能使用任何內建 BigInteger 库, 也不能直接将输入的字符串转换为整数形式。
解析:
class Solution {
public:
string addStrings(string num1, string num2) {
string res;
//定义两个索引分别指向两个字符串末位
int i=num1.size()-1;
int j=num2.size()-1;
//末位运算时相当于进位carry=0;
int carry=0;
//循环条件:当两个字符串没有全部参与过运算,
//或者进位不等于0,运算就要继续下去
while(i>=0||j>=0||carry>0)
{
//对应位上的数字以及上一位的进位相加得到结果carry
if(i>=0)
carry+=num1[i--]-'0';
if(j>=0)
carry+=num2[j--]-'0';
//carry的个位是最终和的对应位
res+=to_string(carry%10);
//carry的十位作为进位参与高一位的运算
carry/=10;
}
//因为我们是从低位到高位的结果,所以返回之前要逆序
reverse(res.begin(),res.end());
return res;
}
};
二进制求和(力扣 67)
给你两个二进制字符串,返回它们的和(用二进制表示)。
输入为 非空 字符串且只包含数字 1
和 0
。
示例 1:
输入: a = "11", b = "1"输出: "100"
示例 2:
输入: a = "1010", b = "1011"输出: "10101"
解析:
class Solution {
public:
string addBinary(string a, string b){
string res;
int carry = 0;
int x, y;
int i = a.size() - 1, j = b.size() - 1;
while ( i >= 0 || j >= 0||carry) {
if(i >= 0 ) carry+= a[i--] - '0';
if(j >= 0 ) carry+= b[j--] - '0';
//思路与上题完全一致.
//只是因为是二进制,在进位时候%,/的周期都是2.
res += carry% 2+'0';
carry /= 2;
}
reverse(res.begin(), res.end());
return res;
}
};
链表求和(力扣 面试题 02.05. )
给定两个用链表表示的整数,每个节点包含一个数位。
这些数位是反向存放的,也就是个位排在链表首部。
编写函数对这两个整数求和,并用链表形式返回结果。
示例:
输入:(7 -> 1 -> 6) + (5 -> 9 -> 2),即617 + 295
输出:2 -> 1 -> 9,即912
进阶:假设这些数位是正向存放的,请再做一遍。
示例:
输入:(6 -> 1 -> 7) + (2 -> 9 -> 5),即617 + 295输出:9 -> 1 -> 2,即912
解析:
class Solution {
public:
ListNode* addTwoNumbers(ListNode* l1, ListNode* l2) {
ListNode* p1=l1;
ListNode*p2= l2;
int sum=0;
int carry=0;
//本题的唯一区别在于,前面操作的是string,这里操作的是链表.
//题目中链表头对应的是低位.若是链表头对应高位,则应当先将链表倒置.
ListNode*res= new ListNode(-1);
ListNode* p=res;
while(p1||p2||carry)
{
if(p1)
{
carry+=p1->val;
p1=p1->next;
}
if(p2)
{
carry+=p2->val;
p2=p2->next;
}
res->next=new ListNode(carry%10);
carry/=10;
res=res->next;
}
return p->next;
}
};
数组形式的整数加法(力扣989)
对于非负整数 X 而言,X 的数组形式是每位数字按从左到右的顺序形成的数组。例如,如果 X = 1231,那么其数组形式为 [1,2,3,1]。
给定非负整数 X 的数组形式 A,返回整数 X+K 的数组形式。
例如:
输入:A = [2,7,4], K = 181,
输出:[4,5,5],
解释:274 + 181 = 455
解析:
//本题的思路与上述三道题完全相同.硬说不同的话,前三道题是两个相同的数
//据结构进行加法运算.这道题是vector 与整数的加法.那么就要求我们
//运用不同的分离方法,从低位分离并运算,
class Solution {
public:
vector<int> addToArrayForm(vector<int>& A, int K) {
//last是A的最低位
int last=A.size()-1;
int carry=0;
while(carry>0||last>=0||K>0)
{
//加和的位数大于A的位数,在A的前面插入高位,初始值0,并且把last位指向0;
//严格意义上讲,一旦运算开始,last应该表示的是当前位
if(last<0)
{
A.insert(A.begin(),0);
last=0;
}
carry=(A[last]+K%10+carry);
A[last]=carry%10;
carry=carry/10;
last--;
K/=10;
}
return A;
}
};
summary:
(末位对齐)
while( 加数A未完 || 加数B未完 || carry!=0 )
{
carry=加数A,B对应位相加+carry;
新位=carry%10;
carry/=10;
加数A换高位;
加数B换高位;
}