关于二进制中1的问题解法汇总

问题:

对于一个字节(8位)的无符号整型变量,求二进制中1的个数。

分析:

法一: 

(n%2)==1则二进制数n的最低位为1,用count记录下,接下来n减半;

n/=2; (比如 11101001变为 01110100)

所以最基础版的代码如下:

int GetAnswer1(unsigned char data)
{
    int count = 0;
    while (data)
    {
        if ((data % 2) == 1)
        {
            count++;
        }
        data /= 2;
    }
    return count;
}

法二:

位操作:

int GetAnswer2(unsigned char data)
{
    int count = 0;
    while (data)
    {
        count+=(data& 0x01);
        data >>= 1;
    }
    return count;
}

法三:

比如0101 1101,目标是1,所以只判断1.

代码:

int GetAnswer3(unsigned char data)
{
    int count = 0;
    while (data)
    {
        data&=(data-1);
    }
    return count;
}

对于法三,详细分析一下:

核心代码是data&=(data-1);

举个例子:

data=1101 1101

data-1=

  1101 1101 

- 0000 0001

=1101  1100

& 1101 1101

= 1101 1100

第一次结果:从最右边开始数起,刚好最低为就为1,所以清零,该位之前的位不变(即红色部分)。

继续:

data-1=

  1101 1100

- 0000 0001

=1101 1011

&1101 1100

=1101 1000

从右往左,遇到0的都变为1,直到遇到1为止,然后清零.

同样1前面的位不变。

接下来同样的操作。。。

所以有几个1就执行几次data&=(data-1)。

法四:

以空间换时间,用一个256大小的数组保存所有的答案,那么查到的的时候就直接O(1)的时间即可。

扩展题目:

第一题:给定两个正整数(二进制表示)A和B,问:把A变为B需要改变多少位?

第一步:    unsigned int x=A^B;(异或操作,位相同为0,不同为1)。

第二步: 判断x中1的个数。

 

第二题:

用一条语句判断一个整数是不是2的整数次方。

分析:

他的二进制位只有一个1,那么就是2的整数次方。

所以:data &= (data-1);

从右往左遇到第一个1清零。

最后判断data是否为0.

  

猜你喜欢

转载自www.cnblogs.com/SunShine-gzw/p/13203021.html
今日推荐