题目:输入一个整数,输出该数二进制表示中1的个数。
// 二进制中1的个数 #include <stdio.h> int wrong_count_1_bits(int n) // 错误解法: 当n为负数时, n>>=1右移, 最高位补1, 陷入死循环
{
int count = ;
while(n)
{
if( n & )
++count;
n >>= ;
}
return count;
} int count_1_bits(int n) // 常规解法, 若sizeof(int)=4, 循环32次
{
unsigned int mask = ;
int count = ;
while(mask) // 循环32次后, mask变为0
{
if( mask & n )
++count;
mask <<= ;
}
return count;
} int perfect_count_1_bits(int n) // 高效解法, 若n含二进制位为1的位数为t, 则循环t次
{
int count = ;
while(n)
{
n = (n-) & n; // 执行该语句后, n的二进制表示中, 最右边的1被置为0, 其余各位不变, 也即是每循环一次, 消去n最靠右的1
++count;
}
return count;
} int static_table_count_1_bits(int n) // 静态表法
{
int table[] =
{
, , , ,
, , , ,
, , , ,
, , ,
}; int count = ;
while (n)
{
count += table[n &0xf] ;
n >>= ;
}
return count ;
} int main(void)
{
printf("sizeof(int)=%d\n",sizeof(int));
printf("%d\n",0x0fffff73); // 非负数正常; 负数(如0xffffff73)会导致程序在wrong_count_1_bits函数处陷入死循环
int count1 = count_1_bits(0x0fffff73);
int count2 = perfect_count_1_bits(0x0fffff73);
int count3 = wrong_count_1_bits(0x0fffff73);
int count4 = static_table_count_1_bits(0x0fffff73);
printf("count1=%d,count2=%d,count3=%d,count4=%d\n",count1,count2,count3,count4); return ;
}
关键点:把一个整数减去1之后再和原来的整数做按位与运算& ,得到的结果相当于把整数的二进制表示中的最右边一个1变成0。
相关题目1:用一条语句判断一个整数是不是2的整数次方
if( (n-1)&n == 0 ) printf("Yes\n");
相关题目2:输入两个整数m和n,计算需要改变m的二进制表示中的多少位才能得到n。
步骤1:求这两个数的异或 t = m^n;
步骤2:统计异或结果t的二进制表示中1的个数,即为需要改变的位数。
相关题目3:二进制中0的个数
方法1:上面常规解法中,改成 if( n^mask == 1 ) ++count;
方法2:先使用上面某种方法求得“二进制中1的个数”,间接求解:sizeof(int)*8 - 1的个数