题目描述
写一个函数,求两个整数之和,要求在函数体内不得使用+、-、*、/四则运算符号。
解法一:
对于这个题我先说一下我自己的思路吧。
- 看到题目,我脑袋里的第一个想法就是用异或(^),类似于全加器(计算机组成原理或者数电中的知识吧,忘了)
- 首先利用(num & 1)分别获取两个整数当前位的值,
tmp1 = num1 & 1;
tmp2 = num2 & 1;
- 然后用 count 当做进位(上一次异或运算的产物),把这三个数字(0 或 1)异或,取得最终结果的当前位数值。
number = tmp1 ^ tmp2 ^ count;//count是上一次循环产生的进位
- 判断是否产生进位 ,感觉应该有其他的方法,以后有机会再补充。
if ((tmp1 == 1 && tmp2 == 1) || (tmp1 == 1 && count == 1) || (tmp2 == 1 && count == 1))
count = 1;else
count = 0;
- 最后把两个整数位右移一位。
num1 = num1 >>> 1;
num2 = num2 >>> 1;
到这里出现一个问题:C++中没有定义无符号右移这个运算符(>>>)。你可以选择自己实现,但是我没试过。
所以我选择下边的方式实现右移,问题解决
num1 = ((unsigned)num1) >> 1;
num2 = ((unsigned)num2) >> 1;
- 要得到运算到这一步为止的结果,那么思路应该是这样的 (sum |= number << n) 。因为当前位的数值要左移 n 位(循环执行的次数),所以又不可避免的要使用加法运算符(n++),也是自己没想清楚就写代码了,好坑啊。
- 那么就需要想其他办法解决这个问题,然后我就想到了栈(stack),把所有的位的值(0 或 1),放进栈中,然后再取出来即可。哎,也是不容易。
class Solution {
public:
int Add(int num1, int num2)
{
stack<int> stc;
int count = 0;//进位
int sum = 0;
int tmp1, tmp2;
int number;
while (num1 != 0 || num2 != 0)
{
//该位数字进栈
tmp1 = num1 & 1;
tmp2 = num2 & 1;
number = tmp1 ^ tmp2 ^ count;
stc.push(number);
//解决进位问题
if ((tmp1 == 1 && tmp2 == 1) || (tmp1 == 1 && count == 1) || (tmp2 == 1 && count == 1))
count = 1;
else
count = 0;
//数字右移问题,这里需要注意有符号右移是左位补零的
//并且C++不支持>>>(无符号右移运算符)
num1 = ((unsigned)num1) >> 1;
num2 = ((unsigned)num2) >> 1;
}
stc.push(count);
while (!stc.empty())
{
sum <<= 1;
sum |= stc.top();
stc.pop();
}
return sum;
}
};