1、常规解法
时间复杂度为O(n)。
n&1 判断n的最低位是不是1,接着1左移一位1<<1判断n的倒数第二位,直到最后。
int numof1{
int count = 0;
usigned int flag=1;
while{
if(n&flag)
count++;
flag=flag<<1;
}
return count;
}
2、时间复杂度为1的个数O(n)。
每次进入循环将最后一个1变为0。
int fun(int n){
int count = 0;
while (n) {
count++;
n = n & (n – 1);
}
return countx;
}
3、基于Hanmming Distance时间复杂度为log(n)。
一个计算相邻2/4/8/16/32位的1的个数。
int count(int num) //假设int是32位
{
int count = num;
int a = 0x55555555; //010101010101010101010101010101 //用于相邻的两位相加
int b = 0x33333333; //用于相邻的四位相加
int c = 0x0f0f0f0f;
int d = 0x00ff00ff;
int e = 0x0000ffff;
count = (count & a) + ((count>>1) & a);
count = (count & b) +((count>>2) & b);
count = (count & c) + ((count>>4) & c);
count = (count & d) + ((count>>8) & d);
count = (count & e) + ((count>>16) & e);
return count;
}
4、
首先是将二进制各位三个一组,求出每组中1的个数,然后相邻两组归并,得到六个一组的1的个数,最后很巧妙的用除63取余得到了结果。
因为2^6 = 64,也就是说 x_0 + x_1 * 64 + x_2 * 64 * 64 = x_0 + x_1 + x_2 (mod 63),这里的等号表示同余。
这个程序只需要十条左右指令,而且不访存,速度很快。
int Count(unsigned x) {
unsigned n;
n = (x >> 1) & 033333333333;
x = x - n;
n = (n >> 1) & 033333333333;
x = x - n;
x = (x + (x >> 3)) & 030707070707;
x = modu(x, 63);
return x;
}