- 1、原创力文档(book118)网站文档一经付费(服务费),不意味着购买了该文档的版权,仅供个人/单位学习、研究之用,不得用于商业用途,未经授权,严禁复制、发行、汇编、翻译或者网络传播等,侵权必究。。
- 2、本站所有内容均由合作方或网友上传,本站不对文档的完整性、权威性及其观点立场正确性做任何保证或承诺!文档内容仅供研究参考,付费前请自行鉴别。如您付费,意味着您自己接受本站规则且自行承担风险,本站不退款、不进行额外附加服务;查看《如何避免下载的几个坑》。如果您已付费下载过本站文档,您可以点击 这里二次下载。
- 3、如文档侵犯商业秘密、侵犯著作权、侵犯人身权等,请点击“版权申诉”(推荐),也可以打举报电话:400-050-0827(电话支持时间:9:00-18:30)。
- 4、该文档为VIP文档,如果想要下载,成为VIP会员后,下载免费。
- 5、成为VIP后,下载本文档将扣除1次下载权益。下载后,不支持退款、换文档。如有疑问请联系我们。
- 6、成为VIP后,您将拥有八大权益,权益包括:VIP文档下载权益、阅读免打扰、文档格式转换、高级专利检索、专属身份标志、高级客服、多端互通、版权登记。
- 7、VIP文档为合作方或网友上传,每下载1次, 网站将根据用户上传文档的质量评分、类型等,对文档贡献者给予高额补贴、流量扶持。如果你也想贡献VIP文档。上传文档
查看更多
求二进制数中1的个数
写书评,赢取《编程之美——微软技术面试心得》/BCZM.asp
求二进制数中1 的个数
对于一个字节(8bit )的变量,求其二进制表示中“1”的个数,要求算法的执行效
率尽可能地高。
写书评,赢取《编程之美——微软技术面试心得》/BCZM.asp
分析与解法
大多数的读者都会有这样的反应:这个题目也太简单了吧,解法似乎也相当地单一,不
会有太多的曲折分析或者峰回路转之处。那么面试者到底能用这个题目考察我们什么呢?事
实上,在编写程序的过程中,根据实际应用的不同,对存储空间或效率的要求也不一样。比
如在 PC 上的程序编写与在嵌入式设备上的程序编写就有很大的差别。我们可以仔细思索一
下如何才能使效率尽可能地“高”。
【解法一】
可以举一个八位的二进制例子来进行分析。对于二进制操作,我们知道,除以一个 2 ,
原来的数字将会减少一个 0。如果除的过程中有余,那么就表示当前位置有一个 1。
以 10 100 010 为例;
第一次除以 2 时,商为 1 010 001 ,余为0。
第二次除以 2 时,商为 101 000 ,余为1。
因此,可以考虑利用整型数据除法的特点,通过相除和判断余数的值来进行分析。于是
有了如下的代码。
代码清单2-1
int Count(int v)
{
int num = 0;
while(v)
{
if(v % 2 == 1)
{
num++;
}
v = v/ 2;
}
return num;
}
【解法二】使用位操作
前面的代码看起来比较复杂。我们知道,向右移位操作同样也可以达到相除的目的。唯
一不同之处在于,移位之后如何来判断是否有 1 存在。对于这个问题,再来看看一个八位的
数字:10 100 001。
在向右移位的过程中,我们会把最后一位直接丢弃。因此,需要判断最后一位是否为 1 ,
而“与”操作可以达到目的。可以把这个八位的数字与进行“与”操作。如果结果为 1 ,
则表示当前八位数的最后一位为 1 ,否则为0。代码如下:
代码清单2-2
写书评,赢取《编程之美——微软技术面试心得》/BCZM.asp
int Count(int v)
{
int num = 0;
While(v)
{
num += v 0x01;
v = 1;
}
return num;
}
【解法三】
位操作比除、余操作的效率高了很多。但是,即使采用位操作,时间复杂度仍为 O
(log v ),log v 为二进制数的位数。那么,还能不能再降低一些复杂度呢?如果有办法让
2 2
算法的复杂度只与“1”的个数有关,复杂度不就能进一步降低了吗?
同样用 10 100 001 来举例。如果只考虑和 1 的个数相关,那么,我们是否能够在每次判
断中,仅与 1 来进行判断呢?
为了简化这个问题,我们考虑只有一个 1 的情况。例如:01 000 000。
如何判断给定的二进制数里面有且仅有一个 1 呢?可以通过判断这个数是否是2 的整数
次幂来实现。另外,如果只和这一个“1”进行判断,如何设计操作呢?我们知道的是,如果
进行这个操作,结果为 0 或为 1 ,就可以得到结论。
如果希望操作后的结果为 0 ,01 000 000 可以和 00 111 111 进行“与”操作。
这样,要进行的操作就是 01 000 000 (01 000 000 – 00 000 001 )= 01 000 000
00 111 111 = 0。
因此就有了解法三的代码:
代码清单2-3
int Count(int v)
{
int num = 0;
while(v)
{
v = (v-1);
num++;
}
return num;
}
【解法四】使用分支操作
解法三的复杂度降低到 O (M ),其中M 是 v 中 1 的个数,可能会有人已经很满足了,
只用计算 1 的位数,这
您可能关注的文档
最近下载
- 北京四惠长途汽车站刻时表.doc VIP
- 创新与创业管理(南京邮电)中国大学MOOC慕课 答案.docx VIP
- 质量安全红线管理专项督查工作手册(第13版)(2).pdf VIP
- 高层建筑结构设计_部分1(共计417页)推荐.ppt
- 2026年时事政治测试题库必考.docx VIP
- 2025年学校领导班子述职述廉报告模版(六).docx VIP
- 创新与创业管理(南京邮电)中国大学MOOC慕课 答案.pdf VIP
- 2026年时事政治测试题库必考.docx VIP
- 2024年陕西省陕西测绘地理信息局下属事业单位考试真题.docx VIP
- 西门子PCS7_8.1软件(内部培训资料).pptx VIP
原创力文档


文档评论(0)