LeetCode第371题,题目如下:不使用运算符 + 和 - ,计算两整数 a 、b 之和。
示例 1:
输入: a = 1, b = 2
输出: 3
示例 2:
输入: a = -2, b = 3
输出: 1
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/sum-of-two-integers
求两数之和,若是不用加号,则就是用计算机组成原理中的加法器实现,即位运算。
解题思路:
1.首先,不知道两个数是正数还是负数,故我们可以将它们当作无符号的数来计算,只不过最后的结果在强转成有符号型即可。
2.根据加法器原理,我们需要一个数sum来记录没有进位时两个数相加的结果,然后需要一个进位器carry来记录在哪个位置该进位,进几位(其实所谓的进位,就可以理解为在要进的位置上加上要进的数即可。)故我们只需将每次的进位左移一个单位,即是要进的位置。
3.最后由sum加上进位器则可得到结果。
4.当然该过程是个循环的,要一直循环到没有进位为止,即进位器变为0。
- a ^ b 为没有进位前的和,即最开始的sum。
- 关于进位:
(1)在二进制中,位相加无非就是四种情况 0 + 0, 0 + 1, 1 + 0, 1 + 1,而在这四种情况中,只有1 + 1这种情况有进位。
(2)故我们想要得到进位器值,便是当a和b的相应的两个位的数都为1,我们可以用 a & b来表示产生进位的位置。
(3)而进位要进的位置是在产生进位的位置前一个,故可以左移一位。
(4)所以我们的进位器表示为 (a & b) << 1。
代码(C++)
//递归方式:
class Solution {
public:
int getSum(int a, int b) {
if(b == 0)
return a;
unsigned int sum = a ^ b;
auto carry = ((unsigned int)(a & b)) << 1;
return getSum(sum, carry);
}
};
//非递归方式:
class Solution {
public:
int getSum(int a, int b) {
while(b)
{
unsigned int sum = a ^ b;
auto carry = ((unsigned int) (a & b)) << 1;
b = carry;
a = sum;
}
return a;
}
};