[LeetCode] 371. Sum of Two Integers

                   371. Sum of Two Integers(Easy)

Calculate the sum of two integers a and b, but you are not allowed to use the operator + and -.

Example:
Given a = 1 and b = 2, return 3.

题意很简单,不使用加减运算符实现两数加法。虽然是道easy难度的题,但是用的是自己不太熟悉的位运算,而且还有另外一个巧妙解法,所以也学到了很多。

常规解法:位运算
由于不能使用普通算术运算的运算符,所以只能想到接近计算机底层硬件方法的二进制计算,此外还有节约内存,提高执行效率的优点。二进制运算实际上就是逻辑运算,在c/c++中有 &(按位与)、|(按位或)、^(按位异或)、~ (按位取反),还有移位运算 << (左移) 和 >> (右移)。
考虑二进制加法,两个单二进制位相加的结果,本位与做异或运算结果相同,而进位与做与运算相同。这样我们就可以用一个数c保存a和b与运算获得的进位,令a和b相加得到本位结果d,再把c左移一位,再与d相加。。。不断重复,直到进位c为零,即运算结束。
代码如下:

class Solution {  
   public:  
      int getSum(int a, int b) {  
          while(b)  
           {  
               int c = a & b;  
               a = a ^ b;  
               b = c << 1;  
           }  
           return a;  
       }  
   };  

巧妙解法:间接利用数组地址自动加法 time: O(1)
虽然不能显式调用加法运算,但后台进行的数组寻址运算实际上就是在进行加法。如果能把a当做数组首地址,而b当做下标,这样a+b运算结果实际上就是a[b]的地址了。
代码如下:

class Solution {
public:
    int getSum(int a, int b) {
        char *c=(char*)a;
        return (long)&c[b];
    }
};

这种方法还有一些可以探讨的细节问题,以及由此对64位机内存机制的进一步了解。若是将上述代码中的char*换成int*,由于此时加数b每加一实际上加了sizeof(int)=4,所以得到的最终结果并不是纯粹的a+b算术运算结果。而由实验得,如果这样运行下来,结果是1+2=9,因为int占4字节,且9在一个字节的表示范围内,由此可以推出本机使用的是little endian。
然后是关于return时将地址转化为整型,若是使用int类型则会报精度丢失的错误,而至少使用了long之后就不会。因此可以推测这里的内存地址表示是在32位以上64位之下的,很有可能是40位。其实这又牵扯到另一个长久以来的疑问,为何在这些IDE里只是用了一部分地址线,而没有用满64位?也许是作为系统给分配内存的一小部分吧,也许还有很多其他复杂的内存管理问题。。。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值