不用四则运算符求A+B问题

刚入门c++,刚打完A+B的程序代码(可能算不上程序-_-!!!)就被学长调戏着问会不会能不能不用+号做A+B问题,当时一脸懵逼,以为有什么神奇的函数和算法,或者什么不入流的赖皮代码,今天偶然学了一下,也来螺旋升天秀一波!

思路流程

这是一道使用位运算的题目,很好,我们可以直接使用二进制来思考,因为c++是支持直接把数当二进制使用的。那么对于每一个位,都只有三种情况:

  1. 0+0=0;
  2. 1+0=1;
  3. 1+1=(1)0; 
    第一种和第二种是很简单的,因为没有进位,我们可以直接使用或运算:|,两者不同(1+0=1)为真,两者相同为假(0+0=0)。因为不存在1+1的进位情况。 
    第三种情况和第一种情况相比,是这题的难点:它们的结果都是0,但显然,它们对答案的影响完全不同! 
    所以,我在想有没有什么操作,可以记录下两个数都为1的情况。好在,有这样一个东西:&,符号与,意思是按二进制,两个位同真为真,其他为假。 
    那么,我们就可以得到一个新的二进制数,它的1表示进位,0表示没有进位。 
    例如,9(1001)+3(11):

 

进位了,之后该如何呢? 
模仿加法的操作,我们相当于让原本加数的下一位+1,相当于,我们多了一个新的加数,“进位数”。所以我们需要两个东西:原本两个数相加的结果(没有进位),以及进位数。 
第一个,刚好又有一个工具:异或,^,它的作用是安位,两位相同取0(0+0=0||1+1=0),否则取1(1+0=1)。 
第二个,我们刚好有另一个工具,位运算: 
a=< < k的意思是,把a的二进制全部左移k位,相当于乘以了2k2k; 
我们用它,就可以很方便的解决这个问题了!进位数左移一位,现在把它和原来的结果相加就可以了! 
最后一个问题:这个时候,相加仍可能进位,能进位怎么相加呢?我们必须找出不进位的结果,所以我们不断重复前两个动作,直至可以不进位相加为止。

 

代码如下:

 1 #include<cstdio>
 2 #include<cstring>
 3 #include<algorithm>
 4 #include<vector>
 5 using namespace std;
 6 int main()
 7 {
 8     int a,b,c;
 9     scanf("%d%d",&a,&b);
10     c=a&b;
11     while(c!=0)
12     {
13         a=a^b;
14         b=c<<1;
15         c=a&b;
16     }
17     printf("%d",a|b);
18     return 0;
19 }

顺便说一下,这个操作的时间复杂度是O(logn),所以除了花式秀操作,并没有什么卵用,但位运算的思想和这几个运算符,在后面会经常用到,所以请熟练它们。 

这个可以很好的加强你对位运算的理解,所以这也不失为一道不错的题

原文地址:https://www.cnblogs.com/genius777/p/8470116.html