下面有三中方法可以实现:
1.可以判断该二进制数的最后一位是否为1,然后右移一位再进行判断,不过当数字为负数时,右移时左边补1,会陷入死循环,最好使用左移。
2.使用左移,将要判断的整数与1进行与运算,判断最后一位是否为1,再将1左移一位,变为10,在进行与运算,判断第二位是否为1,这样循环32次就可以得到该整数中1的个数了,详见下面代码中的find()函数。
3.第二种方法需要循环32次才能得到结果,效率不够好,下面看一个效率较高的算法:
先让整数(n)减一,再和自己进行与运算赋值给n,可以将该整数的最右边的1变为0,将1的个数count++,直到n变为0就可以得到结果,例如1100,减一之后变为1011,进行与运算之后变为1000,一共循环两次就可以得到该二进制中1的个数为2了,详见下面代码中的find2()函数。
代码如下:
#include<iostream> using namespace std; //因为一个int占4个字节(32位),从最低位开始循环32次来统计1的个数 int find(int n) { int count=0; unsigned int temp=1; while(temp) { if(temp & n) count++; temp=temp<<1;//temp左移一位,二进制变成10,判断第二位是否为1 } return count; } //一个数减一再和本身相 与运算,相当于将这个数二进制的最右边的1变为0,有多少个1就循环几次 int find2(int n) { int count=0; while(n) { count++; n=(n-1) & n;//最右边的1变为0,1的个数count++ } return count; } int main() { cout<<find(2)<<endl; cout<<find(-2)<<endl;//负数在计算机中是以补码的形式表示,故-2表示为:2的原码取反+1且最高位为1 cout<<find2(2)<<endl; cout<<find2(-2)<<endl; return 0; }
运行结果如下: