您的位置:首页 > 其它

如何高效的结算一个正整数中二进制表示1的个数

2015-03-29 20:55 253 查看
为了计算一个正整数中二进制表示1的个数。 我们可以采用查表的办法。

下面四位四位的计算:

0000对应0个1

0001对应1 个1

0010 对应1个1

....................

1110 对应3个1

1111对应4个1

所以我们建立如下size为16的数组用于映射0, 1, 2, 3, ....., 15这16个数字对应的整数1的个数。

#include <iostream>

using namespace std;
static int numBits[] = {0, 1, 1, 2,
                        1, 2, 2, 3,
                        1, 2, 2, 3,
                        2, 3, 3, 4};

int bitsCount(unsigned int n) {
    int bitNumber = 0;
    /*
    // 方法二:
    for(; n!= 0; n >>= 4) {
        bitNumber += numBits[n & 0x0f];
    }
    */
    do {
        bitNumber += numBits[n & 0x0f];

    } while(n>>=4); // 注意必须是n>>=4, 不要忘了等号
    return bitNumber;
}

int main() {
    cout << bitsCount(15) << endl;
    return 0;
}


运行结果如下:



方法二: 又被称为Brian Kernighan's algorithm

也就是我们从给定的测试的数减去1, 将会toggles all the bits(from right to left) till the rightest set bit(including the rightestmost set bit)。 so if we subtract a number by a, and do bitwise & with itself(n &(n - 1)), we unset the rightmost set bit. if we do n&(n-1) in a loop
and count the number of times loop executes we get the set bit count. 伪代码如下:

1  Initialize count: = 0
   2  If integer n is not zero
      (a) Do bitwise & with (n-1) and assign the value back to n
          n: = n&(n-1)
      (b) Increment count by 1
      (c) go to step 2
   3  Else return count

程序如下:

#include <cstdio>
int countSetBits(int n) {
    unsigned int c = 0;
    while(n) {
      n &= (n-1) ;
      c++;
    }
    return c;
}

/* Program to test function countSetBits */
int main() {
    int i = 9;
    printf("%d", countSetBits(i));
    return 0;
}

运行如下:

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: