现在的位置: 首页 > 综合 > 正文

编程之美学习笔记之2.1

2018年05月13日 ⁄ 综合 ⁄ 共 881字 ⁄ 字号 评论关闭

问题描述:对于一个字节(8bit)的无符号整形变量,求其二进制表示中“1”的个数,要求算法的执行效率尽可能提高。

解法一:

可以举一个八位的二进制例子来进行分析。对于二进制操作,我们知道,除以一个2.原来的数字会减少一个0.如果除的过程中有余,那么就表示当前位置有一个1.

以10100010为例:第一次除以2时,商为1010001,余为0.第二次除以2时,商为10100,余为1.

代码清单:

int count(BYTE v)

{

  int num=0;

while(v)

{

 if(v%2==1)

 num++;

}

v=v/2;

}

return num:

}

解法二:使用位操作

向右移位除同样可以达到相除的目的。

在向右移位的过程中,我们会把最后一位直接丢弃。因为需要判断最后一位是否为1,而与操作可以达到目的。

代码如下

int count(BYTE V)

{

     int num=0;

 while(v)

 {

 num+=v&0x01;

 v>>1;

 }

 return num;

}

复杂度o(log2v)

解法三

进一步降低复杂度,让算法的复杂度只与“1”的个数有关。

代码如下:

int count(BYTE v)

{

 int num=-0;

while(v)

{

  v&=(v-1);

 num++;

}

return num;

}

解法四:

以空间换取时间:

将所有256种情况都列出来:

int contTable[256] =

{

 0,1,1,2,1,2,2,3,1,...................................}后面的都省略了。

int count(BYTE v)

{

    return coutTable[v];

}

附加题:

另一个相关的问题,给定两个正整数(二进制数表示)A和B,问把A变成B需要改变多少位(bit)?也就是说,整数A和B的二进制表示中有多少位是不同的。

思路:

把两个整数 A, B 异或, 然后又回归到判断 1 的个数
int Count( int a, int b)
{
    int num = 0;
    int v = a ^ b;
    while(v)
    {
       v &= (v-1);
       num++;
    }
    return num;
};

抱歉!评论已关闭.