博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
编程之美读书笔记(1)二进制数中1的个数
阅读量:4104 次
发布时间:2019-05-25

本文共 2595 字,大约阅读时间需要 8 分钟。

问题:

对于一个字节(8bit)的变量,求其二进制中1的个数,要求算法的执行效率尽可能的高。

例如把9表示成二进制是1001,有2位是1,因此如果输入9,1的个数为2。

解法一

可以举一个8位二进制的例子。对于二进制操纵,我们除以一个2,原来数字就会减少一个0(向右移一位)。如果除的过程中有余,那么久表示当前位置有一个1。

以10100010为例:

第一次除以2时,商为1010001,余为0

第二次除以2时,商为101000,余为1

因此,考虑利用整形数据除法的特点,通过相除和判断余数的值进行分析。

int Count(int a){    int count = 0;    while(a)    {         if(a % 2 == 1)         {              count++;           }         a = a / 2;    }    return count;}
解法二:位操作

使用位操作同样达到相除的目的。

使用与操作(&)来判断最后一位是不是1,判断完后向右移一位,继续判断。

可以把这个八位数与00000001进行与操作,如果结果为1则表示这个八位数最后一位为1,否则为0。

int Count(int a){    int count = 0;    while(a)    {         count += a & 0x01;         a >>= 1;    }    return count;}
位操作要比除法取余操作效率要高许多。

解法三:

作者用到一个巧妙的方法,自己与自己减1相与,(例:10100010 & 10100001 = 10100000)从而到达消去最后一位1,通过统计循环次数达到计算1的个数的目的,这个方法减少了一定的循环次数。

具体解析看看原著。

int Count(int a){    int count = 0;    while(a)    {		a = a & (a-1);        count++;    }    return count;}

解法四:分支操作

解法三的复杂度降到O(M). 其中M为1的个数。这效率已经足够高了。

如果还不满足,还有一种方法。既然才是一个8位的数据(0~255),可以直接0~255的情况罗列出来,使用分支操作,得到答案。

这个方法看似很直接,但是效率可能会比其他方法要低。具体情况具体分析。如果a = 0比较一次就会得到答案,但是a = 255比较255次才得到答案

int Count(int a){    int count = 0;    switch(a)    {        case 0x0:             count = 0;             break;        case 0x1:        case 0x2:        case 0x4:        case 0x8:        case 0x10:        case 0x20:        case 0x40:        case 0x80:             count = 1;             break;        case 0x3:        case 0x6:        case 0xc:        case 0x18:        case 0x30:        case 0x60:        case 0xc0:             count = 2;             break;         //.....    }    return count;}

解法五:查表法

直接把0~255相应1的个数直接存在数组中,采取以空间换取时间。

int CountTable[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        };int Count(int a){    return CountTable[a];}

转载地址:http://jwcsi.baihongyu.com/

你可能感兴趣的文章
模块使用
查看>>
miniSipServer简单而不简单,轻松落地,实现电脑对固话、手机通讯
查看>>
【转】TCP/IP协议栈及OSI参考模型详解
查看>>
Pair Project 总结 Part1
查看>>
搭建 vue项目环境
查看>>
自学前端开发 新版css时钟效果图
查看>>
【安全测试自学】初探web安全处测试(二)
查看>>
C++生成随机数:连续均匀分布(uniform distribution)
查看>>
C++中的static函数和extern关键字
查看>>
理解相机的相关参数的设置
查看>>
开发错误记录1:解决:Only the original thread that created a view hierarchy can touch its views....
查看>>
20.20 告警系统主脚本 20.21 告警系统配置文件 20.22 告警系统监控项目
查看>>
centos设置权限
查看>>
POJChallengeRound2 Tree 【数学期望】
查看>>
软工实践作业(四)
查看>>
Mac下搭建svn服务器和XCode配置svn
查看>>
数据库可视化工具简介以及pymysql的使用
查看>>
Linux学习笔记——find查找
查看>>
UVA11853-Paintball(对偶图)
查看>>
OAuth2.0 介绍
查看>>