在C语言中,统计一个整数的二进制表示中1的个数可以通过以下几种方法实现:
一、位运算优化方法(推荐)
利用`n & (n - 1)`的特性,每次操作将最右边的1变为0,直到n变为0。此方法时间复杂度为O(k),其中k是二进制中1的个数。
```c
include
int countones(unsigned long x) {
int count = 0;
while (x) {
count++;
x = x & (x - 1);
}
return count;
}
int main() {
unsigned long num = 29; // 二进制为 11101
printf("Number of 1s in binary: %dn", countones(num));
return 0;
}
```
解释
`x & (x - 1)`:通过减1操作将最右边的1变为0,例如`10011000 & 10010111 = 10010111`。
循环条件`x`不为0时继续执行,直到所有1都被计数。
二、逐位检查方法(效率较低)
通过不断右移并检查最低位是否为1,时间复杂度为O(32)(针对32位整数)。
```c
include
int countones(int n) {
int count = 0;
for (int i = 0; i < 32; i++) {
if ((n & 1) == 1) {
count++;
}
n >>= 1;
}
return count;
}
int main() {
int num = -10; // 二进制为 11111111111111111111111111101110
printf("Number of 1s in binary: %dn", countones(num));
return 0;
}
```
三、分治法(效率较低)
通过检查是否为2的幂次,将问题分解为更小的子问题。
```c
include
int countones(int n) {
int count = 0;
while (n) {
if ((n & (n - 1)) == 0) {
count++;
}
n >>= 1;
}
return count;
}
int main() {
int num = 0b101010; // 二进制为 101010
printf("Number of 1s in binary: %dn", countones(num));
return 0;
}
```
四、其他注意事项
使用`unsigned long`可避免负数右移带来的未定义行为。
位运算方法在1的个数较少时性能更优,而逐位检查法在1的个数接近32时效率较高。
推荐使用 位运算优化方法,既简洁又高效。