这几天一直在牛客上刷笔试题,遇到了两个题,一个题是怎么用二进制表示0的方法,另一个是怎么用二进制表示1的方法,二话不说先上总结:
统计一个数的二进制表示1的方法
先上代码
int func(int x)
{
int count = 0;
while(x)
{
count++;
//消除所有1,变成0
x = x&(x-1);//与运算
}
return count;
}
假设int是占4个字节的,为了使运算方便,我只写4位
当x=6,求count执行的次数?(求6的二进制中1的个数)
①分析:当x=6时
6的二进制 0110
5的二进制 0101
6&5与运算 0100
0100的十进制是4
②当x=4时
4的二进制 0100
3的二进制 0010
4&3与运算 0000
③x=0 循环结束
很显然count执行了两次
综上由代码分析可得:x=x&(x-1);的作用是每次循环把x的二进制数从右往左数的最后一位变成0,直到变成全0的时候,循环结束。
总结:x&(x-1) 的作用是对一个数中二进制1的个数进行统计。
统计一个数的二进制表示0的方法
先上代码:
int fun(unsigned int x)
{
int n=0;
while((x+1))
{
n++;
//消除所有0,变成1
x=x|(x+1);
}
return n;
}
假设int是占4个字节的,为了使运算方便,我只写4位
当x=6时,求n执行的次数?(求6的二进制数中0的个数)
①分析:当x=6时
6的二进制 0110
7的二进制 0111
6|7或运算 0111
0111的十进制是7
②当x=7时
7的二进制 0111
8的二进制 1111
7|8或运算 1111
③1111+0001 =0000 发生了溢出现象 x+1=0 程序退出
很显然n执行了两次
综上代码分析可得:x=x|(x+1);的作用是每次循环把x的二进制中从右往左数的最后一位0变成1,直到变成全1的时候x+1就溢出为全0,循环结束。
总结:x|(x+1) 的作用是对一个数中二进制0的个数进行统计。