您的位置:首页 > 编程语言

求二进制数中"1"的个数

2015-05-11 16:27 141 查看
本题同样来自《编程之美》。

对于一个字节(8bit)的无符号整型变量,求其二进制表示中“1”的个数。

笨方法:

对于二进制操作,除以一个2,原来的数字就会减少一个0.(可以类比十进制,十进制除以一个10,则相应会减少一个0)

如果除的过程中有余,那么就表示当前位置有一个1.

#include<stdio.h>
typedef unsigned char BYTE;
int Count(BYTE v)
{
int num = 0;
while(v)
{
if(v%2==1)
num++;
v=v/2;
}
return num;
}
int main()
{
BYTE b1 = 0;
BYTE b2 = 129;
BYTE b3 = 255;
printf("b1 :%d\n",Count(b1));
printf("b2 :%d\n",Count(b2));
printf("b3 :%d\n",Count(b3));
return 0;
}


好方法:

右移操作同样可以达到相除的目的。

右移后,与00000001进行“与”操作。

int Count(BYTE v)
{
int num = 0;
while(v)
{
num+=v&0x01;
v>>=1;
}
return num;
}



聪明方法:

虽然使用位操作的效率比笨方法高多了,但是,时间复杂度仍为O((log2)v)。

想办法使时间复杂度只与“1”的个数相关。

若v为:01000000,则v-1为:00111111。两者相与为0。

若v为:01100000,则v-1为:01011111。两者相与为01000000。此时和第一种情况一样。再次操作后,为0。

所以,根据这个规律,我们考虑v和v-1相与,统计结果为0之前的次数即为“1”的个数。

int Count(BYTE v)
{
int num = 0;
while(v)
{
v&=(v-1);
num++;
}
return num;
}


此外,还有空间换时间的方法。

将所有的256种情况存储在数组中。

根据v的不同,直接取相应的情况即可。

算法时间复杂度仅为O(1)。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
相关文章推荐