1.利用位运算统计二进制中1的个数
int NumberOfOne(int n)
{
int cnt = 0;
for (;n>0;n=n>>1)
if(n & 0x1) cnt++;
return cnt;
}
int NumberOfOne2(int n)
{
int cnt = 0;
while (n)
{
cnt++;
n = n & (n-1);
}
return cnt;
}
2.利用位运算做加法
如果不考虑进位,两个二进制的相加,便是两个数异或,但是如果存在进位,则结果还要和进位在异或,直到没有进位为止。以5(101)加上17(10001)为例 第一步 10100 但是有进位(00001<<1) 第二步 10100和00010异或 10110 无进位,则结果10110(22)
int Add(int a,int b)
{
int sum,carry;
do
{
sum = a ^ b;
carry = (a & b)<<1;
a = sum;
b = carry;
} while (b!=0);
return a;
}
3.其它用处
比如交换两个数 找出一组数中唯一出现的数字 唯一出现的两个数字等等题目
一个数组中,只有两个数字各出现1次,其它都出现两次
思路:我们知道,两个相同的数字异或结果为0,0与其他数异或等于其他数,那么这组数字异或的结果等于这两个只出现1次的两个数异或,分析这个结果,这个结果的二进制表示中从右往左肯定有一位不为零,则这两个数字一个和结果一样这一位不为零,另一个这一位为零。即选出数字
void FindTheTwo(vector<int> &data)
{
int len = data.size();
int temp = 0,i,j ;
int answer1 = 0, answer2 = 0;
for (i = 0; i < len; ++i)
temp = temp ^ data[i];
for (j = 0; j < 32; ++j)//找到temp中不为零的位置
if(temp>>j && 0x1 == 1) break;
for (i = 0; i < len; ++i)
{
if(data[i]>>j & 0x1) answer1 ^= data[i];
else answer2 ^= data[i];
}
cout<<"The Two Numbers are "<<answer1<<" "<<answer2<<endl;
}