题目:
请实现一个函数,输入一个整数,输出该数二进制表示中1的个数。例如9(1001),有2个1。因此如果输入9,则该函数输出2。
普通法
思路:除2看看余数是不是1,最多循环32次这种方法。
- int Count1(int v)
- {
- int num = 0;
- while ( v )
- {
- if ( 1 == v%2 )
- {
- num++;
- }
- v = v/2;
- }
- return num;
- }
位移法
思路:向右移动一位相当于除2。
- int BitCount1(int v)
- {
- int num = 0;
- for ( ; v; v>>=1 )
- {
- num += v&1;
- }
- return num;
- }
但是如果是负数的话,会出现死循环的情况。
因此,提出了改进版的位移法:(flag向左移)
- int BitCount1Opt(int n)
- {
- int num = 0;
- unsigned int flag = 1;
- while ( flag )
- {
- if ( n&flag )
- {
- num++;
- }
- flag = flag << 1;
- }
- return num;
- }
利用性质的更高效解法
思路:我们发现利用位移计算时,32位的整数需要循环32次。有没有更好的方法呢?整数中有几个1就只需要循环几次。- int NumOf1(int n)
- {
- int count = 0;
- while ( n )
- {
- count++;
- n = (n-1)&n;
- }
- return count;
- }
查表法
首先构造一个包含256个元素的表,table[i]即i对应的二进制数中1的个数。
然后对任意一个32位数分成4个8位,将4个8位中的1的个数相加就是该32位整数中1的个数。
并行法:
平行算法虽然时间复杂度不是很好,但很巧妙。先将n写成二进制形式,然后相邻位相加,重复这个过程,直到只剩下一位。
以217(11011001)为例,有图有真相,下面的图足以说明一切了。217的二进制表示中有5个1
![](https://img-my.csdn.net/uploads/201304/08/1365421955_1153.png)
原文地址:点击打开链接