问题描述
给出两个整数 aa 和 bb , 求他们的和, 但不能使用 ++ 等数学运算符。
说明
a和b都是 32位
整数么?
- 是的
我可以使用位运算符么?
- 当然可以
样例
如果 a=1
并且 b=2
,返回3
。
挑战
显然你可以直接 return a + b,但是你是否可以挑战一下不这样做?
——————————题目分割线——————————
既然提示位运算了,那理所当然的要用位运算解决。正好复习一下位运算操作。先来看看我们经常用到的位运算符:&(按位与)、| (按位或)、^(按位异或)、~(按位取反)、>>(按位右移)、<<(按位左移)。
要实现a+b,要用到什么呢。
试个例子看看吧
5+7 = 101 + 111 = 1100 = 12
额,这里好像有两种思路,一种是一位一位看,考虑进位的话,一共有2^3种组合,a+b为
输入 输出
前一位进位c- a b 产生进位c+ 当前位结果d0 0 0 0 0
0 0 1 0 1
0 1 0 0 1
0 1 1 1 0
1 0 0 0 1
1 0 1 1 0
1 1 0 1 0
1 1 1 1 1
啊,看着头大,怎么通过这个表得出输出和输入的关系的那个推导方式好像是数字逻辑里的内容,我早就还给老师了,但是能观察出来d = a^b^c-。
还是考虑整体方法吧。
思路2:把当前位和进位分开看,当前位的结果可以通过a^b得到,进位可以通过a&b得到,把进位左移一位再和当前位结果相加,利用递归调用,就能得到应得的结果。
嗯,这个思路明确,改成代码
int aplusb(int a, int b) {
if ((a&b) == 0)
{
return a ^ b;
}
else
{
aplusb((a&b) << 1, a^b);
}
代码似乎额外的简单啊
提交也通过了,但是还有点小问题,定义a,b的是int,但是没有报错,思考一下可能是测试集范围或者是服务器是32位服务器导致int取值变大了吧
忽然想到当年学c的时候老师随口说的,一些大公司面试题喜欢出大数相乘,现在想想似乎就可以通过位运算来求解