常用位运算算法题目
位运算操作简单,高效,可以提升算法编程的效率,下面让我们讨论几个常用的位运算算法。
求二进制中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;
}