计算一个数二进制中1 的个数(多种方法)

来源:互联网 发布:安利君软件如何推广 编辑:程序博客网 时间:2024/05/17 06:05

这是一个蛮经典的题。

首先我们会想到最简单的方法就是,用什么方法判断这一位是不是1,如果是1就count++,如果不是就向右移一位, 从新循环。

那么,怎么判断这一位是什么呢。其实很简单,我们只需将这个数和1相与(&),就可以拿到这一个。

下面是代码实现:

#include <iostream>using namespace std;int count_one_bits(int n){int count=0;while(n){if(n&1)count++;n=n>>1;}return count;}int main(){int ret=0;ret = count_one_bits(5);cout<<ret<<endl;system("pause");return 0;}
那么现在问题来了,这个向右移位的操作其实和把整数除以2是相同的,那么可以替换吗?

答案是否定的,应为除法的效率比移位运算符低的多,应该尽量避免使用。

接下来是第二个问题,如果输入一个负数怎么办?

负数输进去当然会错误,应为向右移位时,我们还要保证最左边也是1,那就不好办了。

所以我们可以换个想法,让1向左移就好了。

下面是代码实现:

int count_one_bits(int n){int count=0;unsigned int flag=1;while(flag){if(n&flag)count++;flag=flag<<1;}return count;}int main(){int ret=0;ret = count_one_bits(5);cout<<ret<<endl;system("pause");return 0;}
接下来我们还有一种思路,也是很不错的,那就是让n和n-1相与,也可以得到正确结果。

代码如下:

int count_one_bits(int n){int count=0;while(n){count++;n=n&(n-1);}return count;}int main(){int ret=0;ret = count_one_bits(5);cout<<ret<<endl;system("pause");return 0;}

还有一种很巧妙的方法:

先将n写成二进制形式,然后相邻位相加,重复这个过程,直到只剩下一位。

以217(11011001)为例,有图有真相,下面的图足以说明一切了。217的二进制表示中有5个1 


好了,到这里这个题就算完了。


0 0