统计二进制数中1的个数

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;    
   }  
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值