数字二进制中1的个数

18 篇文章 0 订阅
17 篇文章 1 订阅

     给定一个数字求该数字二进制中1的个数被广泛应用于simhash中,求两个hash值得相似程度可以先将两个hash值做异或操作,然后统计异或结果二进制中1的个数来判断两个hash值得相似性。

    言归正传,求数字二进制中1的位数最直观的解法为所求数字不断的向右移位>>直到为0,统计移位过程中最低位是否是1,这样需要移位32~64位,代码如下:

int bitcout1(uint32_t num){
        int c = 0;
        while(num > 0){
                if(num & 0x1 == 1){
                        c++;
                }
                num >>= 1;
        }
        return c;
}
这种方式直观便于理解,但效率一般,对位运算比较熟悉的同学可能会发现数字减一后会将被减数的二进制中最后一个1变为0,例如7(111)-1 = 6(110),而7和6进行与操作就会将最后的1消除,利用这个原理我们可以这样处理1位数的问题。

int bitcount2(uint32_t num){
        int c = 0;
        for(c = 0; num; c++){
                num &= (num -1);
        }
        return c;
}

算法的复杂度只与数字二进制中1的个数相关,另外在空间复杂度允许的情况下可以直接采用查表法的方式进行计算,这样效率很高
unsigned int table[256] =
    {
        0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4,
        1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5,
        1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5,
        2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
        1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5,
        2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
        2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
        3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7,
        1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5,
        2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
        2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
        3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7,
        2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
        3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7,
        3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7,
        4, 5, 5, 6, 5, 6, 6, 7, 5, 6, 6, 7, 6, 7, 7, 8,
    };
int bitcount7(unsigned int n)
{

    return table[n & 0xff] +
        table[(n >> 8) & 0xff] +
        table[(n >> 16) & 0xff] +
        table[(n >> 24) & 0xff] ;
}

这样的效率是最高的,只不过需要占用一定的空间

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值