统计整数n的二进制表示中1的个数

(1)逐位判断(位运算)

int counter_ones(unsigned n)

{

int counter = 0;

While (n) {

counter += n&1;

n >>=1;

}

return counter;

}

(2)一个整型不为0,那么二进制表示时,至少包含一位1。如果整数减去1,那么最右边的1变成0,而该1后面的0变成1,其余位不变。将原来的整数和减去1后的数做与运算,从原来最右边的那个1开始所有的,所有位变成0,如:1100&(1100-1=1011)=1000。也就是说整数与该数-1后做与运算,会把最右边一个1变成0。

int counter_ones(unsigned n)

{

int counter = 0;

While (n) {

counter++;

n &= (n-1);

}

return counter;

}

(3)查表法

将32位(64位)整型数分切割成n个区间,每个区间位长位8。分别统计每个位区间中1个个数,然后相加。

static const unsigned char BitsSetTable256[256] =

{

#   define B2(n) n,     n+1,     n+1,     n+2

#   define B4(n) B2(n), B2(n+1), B2(n+1), B2(n+2)

#   define B6(n) B4(n), B4(n+1), B4(n+1), B4(n+2)

B6(0), B6(1), B6(1), B6(2)

};

int counter_ones(unsigned n)

{

int counter = 0;

for (; n > 0; n >> 8) {

counter += BitsSetTable256[n&255];

}

return counter;

}

Or

int counter_ones(unsigned n)

{

char *p = (char *)&n;

return BitsSetTable256[*p] + BitsSetTable256[*(p+1)] + BitsSetTable256[*(p+2)] + BitsSetTable256[*(p+3)]

}

(4)归并法。

对于一个32位整数,先分成16组,每组2位,统计其中1个数,然后将统计的结果两两合并,得到8组,然后再此基础上,合并得到4,2,1,最总得到结果。

int counter_ones(unsigned n)

{

n = (n & 0x55555555) + ((n >> 1) & 0x55555555);

n = (n & 0x33333333) + ((n >> 2) & 0x33333333);

n = (n & 0x0f0f0f0f) + ((n >> 4) & 0x0f0f0f0f);

n = (n & 0x00ff00ff) + ((n >> 8) & 0x00ff00ff);

n = (n & 0x0000ffff) + ((n >> 16) & 0x0000ffff);

return n;

}

参考:http://graphics.stanford.edu/~seander/bithacks.html#CountBitsSetNaive

时间: 2024-07-31 20:03:36

统计整数n的二进制表示中1的个数的相关文章

统计整型数据二进制形式中1的个数

统计整型数据二进制形式中1的个数可以通过如下方式达到: int cnt1bits(int x) { int count = 0; while (x) { ++count; x = x & (x - 1); } return count; }

统计一个无符号整数的二进制表示中1的个数

#include <stdio.h>int countbit(unsigned int x); int main(void) { int x,n; printf("请输入一个无符号整数:\n"); scanf("%d",&n); x=countbit(n); printf("%d\n",x); } int countbit(unsigned int x) { unsigned int c=0; while(x>0) {

【C语言】输入一个整数,输出该数二进制表示中1的个数(三种方法)

输入一个整数,输出该数二进制表示中1的个数.如输入32,输出1. 代码实现: 方法1:与运算 #define _CRT_SECURE_NO_WARNINGS 1 #include<iostream> using namespace std; int FindOneNumber(unsigned int num) {     int numberofOne = 0;     while (num)     {         num = num & (num - 1);         

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

输入一个整数,输出该数二进制表示中1的个数.其中负数用补码表示. 思路: n &(n-1)把n的最右边的1去掉,用count++计算1的个数  eg: 101 & 100 = 100   1 class Solution { 2 public: 3 int NumberOf1(int n) { 4 int count = 0; 5             while(n!=0){ 6                 count++; 7                 n = n&

剑指offer11:输入一个整数,输出该数二进制表示中1的个数。其中负数用补码表示。(进制转换,补码反码)

1. 题目描述 输入一个整数,输出该数二进制表示中1的个数.其中负数用补码表示. 2. 思路和方法 使用移位(<<)和 “| & !”操作来实现.1的二进制是:前面都是0,最后一位为1.每次向左移位一下,使得flag的二进制表示中始终只有一个位为1,每次与n做位与操作,这样就相当于逐个检测n的每一位是否是1.unsigned int flag = 1; 3. C++核心代码 3.1 位运算 1 class Solution { 2 public: 3 int NumberOf1(int

整数的二进制表示中1的个数

给出通常能想到的方式,这两种方式在<C和指针>一书中给出.以下讨论的均为非负整数. /* 该方法每次在循环中判断数的二进制最右一位是否为1(如果该数能不能被2整除). 每次循环后该数右移一位.因此遍历了数的二进制表示的每一位. */ int count_one_bits1(int value) { int count; for (count = 0; value != 0; value >>= 1) if (value % 2 != 0) count++; return count

位运算--统计一个数的二进制序列中1的个数

给出一个十进制数,求出该数的二进制序列中1的个数.比如 15 的二进制序列是 00000000  00000000  00000000 00001111   1的个数是4. 下边将给出几种不同的解决办法: 方法一: int count_one(int num) { int count = 0; while (num) { if (num % 2 == 1) { count++; } num = num / 2; } return count; } 由于这种方法用到了模除运算,所以这个方法只能处理

每天一道算法题:数字二进制形式中1的个数

题目:请实现一个函数,属于一个整数,输出该数二进制表示中1的个数,例如把9表示成二进制是1001,有2位为1.因此如果输入9,该函数输出2. 可能的死循环陷阱 看完题目,相信大家很快就能想到一个解题思路:先判断整数二进制表示中最右边的一位是否为1,接着把输入的整数右移一位,此时原来处于从右边起的第二位被移动至最右边了,再判断是不是1,这样每次移动一位,直到这个整数变成0,即能够得到整数二进制表示形式中1的个数,而现在问题变为如何判断数字的最后一位为1,其实这个也很简单,只需要将数字与1做与运算,

一个数的二进制表示中1的个数——10

实现一个函数,输入一个整数,输出该数二进制表示中1的个数.例如,将9表示成二进制为1001,有2位是1,因此如果输入数字9,该函数输出2. 如果让我们将一个十进制的数转换成二进制的表示,我们就会不停的模除模除2取它的余数,因此,就可以用这样的方法解决: #include <iostream> using namespace std; size_t count_one_num(int n) {     size_t count = 0;     while(n != 0)     {