二进制中1的个数

平行算法

int BitCount(unsigned int 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 ;
}

先说n &0x55555555,操作如下:

abcdefgh010101010b0d0f0hhijklmno010101010i0k0m0opqrstuvw010101010q0s0u0wxyzabcde010101010y0a0c0e

再说(n >>1) &0x55555555,操作如下:

0abcdefg010101010a0c0e0ghhijklmn010101010h0j0l0nopqrstuv010101010p0r0t0vwxyzabcd010101010x0z0b0d

于是乎,n = (n &0x55555555) + ((n >>1) &0x55555555)应该是:

+0b0d0f0h0a0c0e0g0i0k0m0o0h0j0l0n0q0s0u0w0p0r0t0v0y0a0c0e0x0z0b0d

可知上述这一行代码实际是实现了相邻的两个二进制二相加,后面代码一次是相邻2位、4位、8位···二进制位相加,实现了二进制数中对1的个数的统计功能。以217(11011001)为例,有图有真相,下面的图足以说明一切了。217的二进制表示中有5个1
这里写图片描述
总结:运用了分治法计算二进制数中1的个数,
(n & 0x55555555) + ((n >> 1) & 0x55555555) 计算每对相邻的2位中有几个1
(n & 0x33333333) + ((n >> 2) & 0x33333333) 计算每相邻的4位中有几个1
接下来8位,16位,32位,对于32位的机器,5条位运算语句就够了。

快速法

int BitCount(unsigned int n)
{
    unsigned int c =0 ;
    for (c =0; n; ++c)
    {
        n &= (n -1) ; // 清除最低位的1
    }
    return c ;
}

更多方法参见【这里】

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值