A+B问题

lintcode算法题 1. A + B 问题

描述给出两个整数 a 和 b , 求他们的和。你不需要从输入流读入数据,只需要根据aplusb的两个参数a和b,计算他们的和并返回就行。

说明 a和b都是 32位 整数么? 是的。我可以使用位运算符么? 当然可以

样例 如果 a=1 并且 b=2,返回3。

挑战 显然你可以直接 return a + b,但是你是否可以挑战一下不这样做?(不使用++等算数运算符)

代码:Talk is cheap. Show me the code.

int add(int a,int b){

    if(b==0){       

        return a;   

    }else{       

        return add(a^b,(a&b)<<1);   

    }

}

分析:

这道题用到的是位运算,位运算符中与加有关的首先想到的是异或运算。

1. 异或:相异为1,相同为0。

特殊情况下,异或运算的结果与+相同。比如5和2

5+2 = 0101 + 0010 = 0111 = 7

5^2 = 0101 ^ 0010 = 0111 = 7

结果都是7。在5和2的二进制加法中刚好不存在进位,如果存在进位那又是什么情况呢。比如6和2

6+2 = 0110 + 0010 =1000 = 8

6^2 = 0110 ^ 0010 = 0010 = 2

可见,当需要进位的时候结果就不相同了。所以不需要进位的我们可以用异或,需要进位的我们继续分析。

2. 左移:把所有二进制位左移n位,右边补0(这里不考虑有符号无符号和溢出的问题)。

对于二进制进位,首选左移。左移一位相当于给所有是1的位进位一次,比如

3 << 1 = 0011 << 1 = 0110 = 6

回归我们的问题,进位有了,剩下的我们要找出哪些位需要进位,也就是那些位在两个加数里都是1,这里就又需要一个新的位运算 与

3. 与:都是1为1,否则为0。

在我们的问题中,与运算后为1的位需要进位。即a&b的结果需要进位,进位用左移,即(a&b)<<1 可以计算出进位后的结果。

整个计算过程是这样的

1.  先异或(a^b): 筛选不能进位的二进制位 标记为1 计算出中间数b1。

2. 然后与(a&b): 筛选需要进位的二进制位 标记为1 ;再左移((a&b)<<1) 理解为 进位 对需要进位的二进制位进位 计算出中间数a1。

3.注意:此时的 a1+b1 == a+b。把a1看作a,把b1看作b,继续1,2步骤,直到b==0,也就是没有需要进位的二进制位。此时的a就是原来的a+b的结果。

例子:

a = 15 , b = 22 求 a+b

-------------------------------

第一轮运算

     a = 15    0000 1111   a原值

      b = 22    0001 0110  b原值

    a^b = 25    0001 1001  筛选出的不需要进位的位,计作a1

    a&b =  6    0000 0110 筛选出的需要进位的位

 a&b<<1 = 12    0000 1100 给需要进位的位 进位,结果计作b1

 -------------------------------

第二轮运算

      a = 25    0001 1001  第一轮计算出的a1

      b = 12    0000 1100 第一轮计算出的b1

    a^b = 21    0001 0101

    a&b =  8    0000 1000

 a&b<<1 = 16    0001 0000

 -------------------------------

第三轮运算

      a = 21    0001 0101

      b = 16    0001 0000

    a^b =  5    0000 0101

    a&b = 16    0001 0000

 a&b<<1 = 32    0010 0000

 -------------------------------

第四轮运算

      a =  5    0000 0101

      b = 32    0010 0000

    a^b = 37    0010 0101

    a&b =  0    0000 0000

 a&b<<1 =  0    0000 0000

 -------------------------------

第五轮运算,此时b==0,a即运算结果。

      a = 37    0010 0101

      b =  0    0000 0000

 -------------------------------

结果

    a+b = 37

 -------------------------------


最后

初学者 参考了网上很多资料搞明白的,感谢各位乐于分享的大神,希望可以给以后同学一点帮助。如有错误,欢迎指正。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 我是小小强,这是我的第5篇原创文章,阅读需要大约10分钟。 题目 LintCode:A+B问题 描述 给出两个整数...
    我叫小小强阅读 300评论 0 3
  • 网站乱码问题我们会经常碰到,大多见于非英文的中文字符或其他字符乱码,而且,这类问题常常是因为编码方式问题,主要原因...
    波段顶底阅读 3,021评论 1 9
  • 版权声明:本文参考网络文章。 难度:普通 要求: 给出两个整数a和b, 求他们的和, 但不能使用 +等数学运算符。...
    柒黍阅读 1,535评论 0 2
  • 看了波哥的计划,颇有震撼,自己完成不了那么多,我来个精简版的。 家庭: 每周给爸爸、妈妈、姐姐、姐夫、申萌、申逗各...
    Inker阅读 253评论 0 4
  • 前同事W最近又离职了,理由是现在的岗位太没有前景了,上司总压制着自己,什么想法都实现不了。行业竞争残酷,公司规矩也...
    零零鱼阅读 254评论 1 1