常用位运算算法题目

常用位运算算法题目

位运算操作简单,高效,可以提升算法编程的效率,下面让我们讨论几个常用的位运算算法。


求二进制中1的个数

这个题目有在编程之美里面出现,最基本的思路就是一个数除以2,原来的二进制数目会减少一个,若是除的过程中有余数,那么就表示当前位置有一个1.

除以2可以用>>操作,判断是否有余数1可以用&操作。

int hammingWeight(uint32_t n) 
{
     int num=0;
     while(n)
     {
         if(v%2==1) 
             num++;
         n=n>>1;
     }  
     return num;
}

当然上述最直接的方法的时间复杂度为O(v),v是二进制串的长度。还有一种O(logv)时间复杂度的方法。代码如下:

int hammingWeight(uint32_t n) 
{
     int num=0;
     while(n)
     {
         n &=(n-1);
         num++;
     }  
     return num;
}

其中v=v&(v-1)是为了消除二进制串的最后一位1.例如v=1010000,那么v-1=101111.那么v&(v-1)=1000000。每进行这样的一次操作就进行一次计数,最后得到二进制串中的1个数目。

此外,还有很多算法,大家可以自己研究查询。

Single Number 问题

问题描述:数组中有n个元素,其中除一个元素出现过一次外,每个元素都出现过两次,找到出现过一次的那个元素。

思路很简单,遍历数组,不断进行异或运算。
result= a[0] ^a[1]…..a[n-1],想想异或运算是满足交换律结合律的撒,那么出现过两次元素的异或之后为0,最终剩下的就是只出现过一次的那个元素。代码如下:

int singleNumber(int A[], int n) 
{
     for (int i = 1; i < n; ++i)
         A[0] ^= A[i];
     return A[0];
}

Reverse Bits 问题

问题描述:将二进制串的值逆转。如10011,逆转之后为11001。
一般思路就是将后面的位一步步放到前面去。代码如下:

uint32_t reverseBits(uint32_t n) {
        uint32_t m=0;
        for(int i=0;i<32;i++){
            m<<=1;
            m = m|(n & 1);//每次将二进制串的最后一位放到m的最后一位
            n>>=1;
        }
        return m;
    }

代码还可以进一步精简为:

uint32_t reverseBits(uint32_t n) {
    uint32_t bin=0;
    for (i = 0; i < 32; i++) 
         bin+=(n >> i & 1)<<(31-i);
    return bin;
}

你可能感兴趣的:(算法,位运算,算法)