• 关于二进制中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.

      

  • 相关阅读:
    通过AOP引入Log4j
    Spring和Spring MVC框架进行单元测试
    JAVA异常基本知识及异常在Spring框架中的整体解决方案
    JAVA基础之重载,覆盖/重写,多态
    JAVA基础之内存
    JAVA基础之数组
    软件设计模式的原则
    ecstore 新增模块(页面)
    gitstack 密码重置
    thinkphp3.2整合workerman 多入口模式(windows)
  • 原文地址:https://www.cnblogs.com/SunShine-gzw/p/13203021.html
Copyright © 2020-2023  润新知