二进制中1的个数

题目描述 :

  输入一个整数,输出该数二进制表示中1的个数。其中负数用补码表示。

方法1:手动转化法

  直接想到的就是手动把数转化为二进制存进vector里,然后去数1的个数。当然这个很麻烦的地方在于负数是用补码,你把绝对值转化成二进制之后还得变成补码,工作量太多。

方法2:整数移位法

  编程语言提供了位运算符,比如&(与)、|(或)、<<(左移)、>>(右移)等,位运算都是以二进制来操作的。
  我们可以把这个整数不断右移,每右移一次就判定一次末尾是不是1,一直右移到这个数变成0。判定末尾的方法是和1作相与操作,与之后是1则说明原数这一位是1。
  代码如下:

int count_one_way1(int num)
{
    int counts=0;
    while(num)
    {
        if((num&1)==1)
            counts++;
        num=num>>1;
    }
    return counts;
}

  但是这段代码有问题,问题在于右移补位的时候,正数补0,而负数补1,所以如果num是个负数,会陷入死循环。

方法3:1移位法

  为了避免上述问题,有一个改进方法是不移原来的数,我们把1这个数不断左移,和原数的每一位作相与,然后每次想与的结果不是0,就说明原数这一位是1。
  代码如下:

int count_one_way2(int num)
{
    int counts=0;
    int t=1;
    while(t!=0)
    {
        if((num&t)!=0)
            counts++;
        t=t<<1;
    }
    return counts;
}

  这里会t会一直左移,本机int有多少位,t就会移动多少位,也就是会和num的每一位都比较到。

方法4:相邻数相与法

  有一个很巧妙的方法是,n和n-1的相与结果,可以消掉n最右边的1。比如说11-00&1011=1000。所以我们只需要不断执行这种操作,就可以知道n有多少个1了。
  代码如下:

int count_one_way3(int num)
{
    int counts=0;
    while(num)
    {
        counts++;
        num=num&(num-1);
    }
    return counts;
}

方法5:函数法

  c++有头文件提供了这个功能,这里尖括号里是32是因为我的电脑的int型是32位。

#include<bitset>
int count_one_way4(int num)
{
    return bitset<32>(num).count();
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章