求二进制中1的个数

解法有很多种:以一个字节无符号字节变量作为例子

解法一:求余法

在将十进制数转换为二进制数时,采用除2取余法。将每次除2得到的余数保存起来逆序输出便是该十进制整数的二进制表示。因此可以采用这种方法去统计1的个数。

public int count(byte n)
{
    int sum=0;
    while(n)
    {
        if(n%2==1)
            sum++;
        n/=2;
    }
    return sum;
}
解法二:位运算

public int count(byte n)
{
    int sum=0;
    while(n)
    {
        sum+=n&0x01;
        n>>=1;
    }
    return sum;
}

解法三:快速法

2中所述方法的循环次数始终为8,有一种方法可以减少这个循环次数。就是采用减1再进行与的运算,这样每进行一次,就会少一个1.

比如: 0010 0110 减1得 0010 0101 &0010 0110等于0010 0100.原因在于比如r1r2...rn,如果最后面位1的一位为rk,则该数减1之后二进制的表示形式中rk肯定为0,但是r(k+1)...rn则全部为1,与原来的数进行与操作不会印象到rk前面的1的个数,因此每进行一次,则可以消去一个二进制1。

public int count(byte n)
{
    int sum=0;
    while(n)
    {
        n&=(n-1);
        sum++;
    }
    return sum;
}
例如:0100 0010&0100 0001 = 0100 0000 sum=1, 0100 0000&0011 1111 = 0000 0000 sum=2,exit; 


解法四:查表法

一个字节的无符号整型数据范围就在[0,255]之间,因此可以直接定义一个长度为256的数组table[0-255],把0-255二进制表示中1的1的个数赋给数组的元素,这样直接进行查找。

不适合比较大的数

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, 
            };

public int count(byte n)
{
    return table[n];
}
问题扩展:给定两个整数A和B(二进制表示),问把A变为B需要改变多少位?也就是说,A和B的二进制表示中有多少位是不同的。

解:

1:利用位运算的方法每次求出A和B最低位数然后进行比较是否相等,不相等+1即可。

2:先将A和B异或,然后使用快速法,求其中1的个数即可。


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值