
孙老师为您分享以下优质知识
在C语言中,统计一个整数的二进制表示中1的个数可以通过多种方法实现,以下是常见的几种方法及代码示例:
一、逐位检查法(最直观的方法)
通过循环检查每一位是否为1,每检查一位就将计数器加1,然后将数字右移一位。
```c
include
int countones(unsigned int n) {
int count = 0;
while (n) {
count += n & 1; // 检查最低位是否为1
n >
>
= 1;// 右移一位
}
return count;
}
int main() {
unsigned int num = 29; // 二进制为11101
printf("Number of 1s in binary: %dn", countones(num));
return 0;
}
```
二、位运算优化法(效率更高)
利用`n & (n - 1)`的特性,每次操作可以消除最低位的1,直到数字变为0。
```c
include
int countones(unsigned int n) {
int count = 0;
while (n) {
n &= (n - 1); // 消除最低位的1
count++;
}
return count;
}
int main() {
unsigned int num = 29; // 二进制为11101
printf("Number of 1s in binary: %dn", countones(num));
return 0;
}
```
三、查表法(适用于固定位数)
预先计算0-255每个数的二进制中1的个数,通过查表获取结果(适用于32位整数)。
```c
include
unsigned char onesTable = {
0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4,
// ...(完整表略)
};
int countones(unsigned int n) {
return onesTable[n & 0xFF];
}
int main() {
unsigned int num = 29; // 二进制为11101
printf("Number of 1s in binary: %dn", countones(num));
return 0;
}
```
四、处理负数的方法
上述方法仅适用于非负整数。对于负数,可以使用补码表示,但需先将其转换为无符号数。
```c
include
int countones(int n) {
unsigned int unsigned_n = (unsigned int)n;
return countones(unsigned_n);
}
int main() {
int num = -29; // 补码表示为11101011
printf("Number of 1s in binary: %dn", countones(num));
return 0;
}
```
总结
逐位检查法简单易懂,但效率较低,时间复杂度为O(k),其中k是二进制中1的个数。
位运算优化法效率更高,时间复杂度为O(k)。
查表法适用于固定位数(如32位),但需额外空间存储查表。
负数处理需先转换为无符号数再统计。
根据实际需求选择合适的方法,例如在性能敏感的场景下优先使用位运算优化法。