面试题 47

来源:互联网 发布:mac os虚拟机 编辑:程序博客网 时间:2024/05/16 06:14

本节介绍有关位操作的算法

剑指offer中提到了一个经典面试题目,就是不用加减乘除实现两个数字的加法。
作者的代码如下:

#include<iostream>using namespace std;void add(int num1,int num2){    int sum;    int carry;    do    {        sum = num1^num2;        carry = (num1&num2) << 1;        num1 = sum;        num2 = carry;    } while (num2 != 0);    cout << num1 << endl;}int main(){    add(3,24);    return 0; }

我们来分析一下作者算法的核心,我在这里用自己语言描述一下,首先我们要知道位操作的几种运算
位操作主要有五种运算,分别是与、或、异或、左移、右移。
我们进行要知道进行两个数的加法运算就是进行两部分操作,一个是相对位置相加,一个是进位。如果我们能实现以上两项。我们先来看一下相对位置相加的操作,1加1、0加0的结果都会是0,因为1加1需要进位,所以当前位会变成0,1加0和0加1都是1,综合以上用异或运算。再看一下进位,我们要对相对位置进行1加1为1,其他的相对位置都为0,然后结果左移1位,我们可以举个例子,01和01的进位是10。
以上就是主要的理论细节。

现在我们想一下如果搞定下面的这个面试题。
如何在不用加减乘除的情况下得出一个数字6倍的值。
现在这个问题我们可以用上面的程序,
代码如下:

#include<iostream>using namespace std;void add(int num1,int num2){    int sum;    int carry;    do    {        sum = num1^num2;        carry = (num1&num2) << 1;        num1 = sum;        num2 = carry;    } while (num2 != 0);    cout << num1 << endl;}int main(){    add(3 << 2, (3 << 1));    return 0; }
1 0