算法学习(6)----不用 +

  今天网上看到一个神算法,惊异不已,遂摘录于下:

原文地址:http://blog.csdn.net/sanniao/article/details/47106713

第一步不考虑进位,对每一位相加。0加0 1加1的结果都0,0加1与1加0的结果都是1。我们可以注意到,这和异或的结果是一样的。对异或而言,0和0、1和1异或的结果是0,而0和1、1和0的异或结果是1。接着考虑第二步进位,对0加0、0加1、1加0而言,都不会产生进位,只有1加1时,会向前产生一个进位。此时我们可以想象成是两个数先做位与运算,然后再向左移动一位。只有两个数都是1的时候,位与得到的结果是1,其余都是0。第三步把前两个步骤的结果相加。如果我们定义一个函数AddWithoutArithmetic,第三步就相当于输入前两步骤的结果来递归调用自己。

有了这些分析之后,就不难写出如下的代码了:

int AddWithoutArithmetic(int num1, int num2)

{

        if(num2 == 0)

                return num1;

        int sum = num1 ^ num2;

        int carry = (num1 & num2) << 1;

        return AddWithoutArithmetic(sum, carry);

}

后面网友给出了另外一种巧妙方法,利用地址偏移实现加法,代码如下:

int add(int a,int b){
    char * c;
    c = (char *) a;
    return &c[b];
}

着实令我感叹的是第二个算法,解析如下:

  对于一个数组 int arrInt[], arrInt[i]等同于 *(arrInt+i); 因为一个 int 型变量占用4个字节,所以 arrInt+i 在数值上等同于 arrInt+4*i;因此,为了达到实际想要的 arrInt+i 的效果,可以使用 char 型数组 char arrChar[], 这样 arrChar[i] 就等同于 *(arrChar+i) ,而且 arrChar+i 就是 arrChar+i。

  这个巧妙算法正是利用了这种思想,先把 int 型的 a 强制转换为 char 型指针 c, 那么 c[b] 就等同于 *(c+b) ,也就是*(a+b),然后用取地址运算符 & 去掉 * 的作用,所以 &c[b] 就等同于 (c+b),也就是 a+b 了。

原文地址:https://www.cnblogs.com/dongling/p/5767444.html