10、二进制中1的个数

  题目:请实现一个函数,输入一个整数,输出该数二进制表示中1的个数。例如把9表示成二进制是1001,有2位是1。因此如果输入9,该函数输出2。

  思路:先判断是否为0,如果非0则至少有一个1,设置一个变量计数1的个数,然后将该二进制数减1,减完之后与原来的数做与运算,这样这个1就会消失。重复这样操作,每次这个变量加1,直到所有1消失。
  例: 1100。判断非0,所以变量+1,然后减1,就变为1011,再与1100做与运算,得1000,变量再+1,然后1000再减1,得0111,再与1000做与运算,得0,结束。得到2个1。

  测试用例
  1.正数(包括边界值1、0x7FFFFFFF)。
  2.负数(包括边界值0x80000000、0xFFFFFFFF)。
  3.0

#include<iostream>
using namespace std;

int NumberOf1(int n)
{
    int count = 0;

    while (n)
    {
        ++count;
        n = (n - 1) & n;
    }

    return count;
}

//测试
void test1()
{
    int n1 = 1;
    int n2 = 0x7FFFFFFF;
    int count1 = NumberOf1(n1);
    int count2 = NumberOf1(n2);
    cout << count1 << endl;
    cout << count2 << endl;
}

void test2()
{
    int n1 = 0x80000000;
    int n2 = 0xFFFFFFFF; //取反加1
    int count3 = NumberOf1(n1);
    int count4 = NumberOf1(n2);
    cout << count3 << endl;
    cout << count4 << endl;
}

void test3()
{
    int n = 0;
    cout << NumberOf1(n) << endl;
}

int main()
{
    test1();
    test2();
    test3();

    return 0;
}

  相关题目
  
  题目:用一条语句判断一个整数是不是2的整数次方。

  思路:一个正数如果是2的整数次方,那么它的二进制表示中有且只有一位是1,而其他所有位都是0。根据前面的分析,把这个整数减去1之后再和它自己做与运算,这个整数中唯一的1就会变成0.


  题目:输入两个整数m和n,计算需要改变m的二进制表示中的多少位才能得到n。比如10的二进制表示为1010,13的二进制表示为1101,需要改变1010中的3位才能得到1101.

  思路:第一步求这两个数的异或,不同的位就会为1,第二步统计1的个数。


  举一反三
  把一个整数减去1之后再和原来的整数做位与运算,得到的结果相当于是把整数的二进制表示中的最右边一个1变成0,很多二进制问题都可以用这个思路解决。

猜你喜欢

转载自my.oschina.net/134596/blog/1794979