更多题目请点链接:《剑指offer》目录索引
问题描述:
请实现一个函数,输入一个整数,输出该数二进制表示中1的个数。例如:把9表示成二进制是1001,有2位是1。因此如果输入9,该函数输出2
思路1:
求二进制1的个数,首先想到操作符&(按位与),&规则:0&1=1 1&1=1
采用&的规则,对应的二进制位&1,并统计1的个数
例:求9的二进制有几个1
9 & 1 (由于二进制序列前面都是0,故只写低8位):
0000 1001
0000 0001 & 1
0000 0001
按位与1的结果判断最低位是1;
之后每次将1左移一位,可判断剩余的每一位是否为1
代码:
int NumberOfOneCount(int n)
{
int count=0;
unsigned int flag=1;
while(flag)
{
if((n&flag)!=0)
{
count++;
}
flag = flag<<1;
}
return count;
}
注意:下面这句代码不可写成if((n&flag)==1);因为flag左移后的二进制序列对应的不是1
if((n&flag)!=0)
思路2:
上面的算法每次循环32次,效率较低,因此采用下面这种算法:n&(n-1) 这种算法的循环次数为二进制序列中1的个数
例:
9 的二进制序列:0000 1001
8 的二进制序列:0000 1000
按位与后的序列:0000 1000
此时count为1,n=8
8 的二进制序列:0000 1000
7 的二进制序列:0000 0111
按位与后的序列:0000 0000
此时count为2,即为9的二进制序列1的个数
代码:
int NumberOfOneCount1(int n)
{
int count=0;
while(n>0)
{
count++;
n=n&(n-1);
}
return count;
}
测试代码及结果:
void Test()
{
printf("%d ",NumberOfOneCount(0));
printf("%d ",NumberOfOneCount(1));
printf("%d ",NumberOfOneCount(2));
printf("%d ",NumberOfOneCount(3));
printf("%d ",NumberOfOneCount(4));
printf("%d ",NumberOfOneCount(5));
}
void Test1()
{
printf("%d ",NumberOfOneCount(0));
printf("%d ",NumberOfOneCount(1));
printf("%d ",NumberOfOneCount(2));
printf("%d ",NumberOfOneCount(3));
printf("%d ",NumberOfOneCount(4));
printf("%d\n",NumberOfOneCount(5));
}
结果: