求二进制数中1的个数.PDFVIP

  1. 1、原创力文档(book118)网站文档一经付费(服务费),不意味着购买了该文档的版权,仅供个人/单位学习、研究之用,不得用于商业用途,未经授权,严禁复制、发行、汇编、翻译或者网络传播等,侵权必究。。
  2. 2、本站所有内容均由合作方或网友上传,本站不对文档的完整性、权威性及其观点立场正确性做任何保证或承诺!文档内容仅供研究参考,付费前请自行鉴别。如您付费,意味着您自己接受本站规则且自行承担风险,本站不退款、不进行额外附加服务;查看《如何避免下载的几个坑》。如果您已付费下载过本站文档,您可以点击 这里二次下载
  3. 3、如文档侵犯商业秘密、侵犯著作权、侵犯人身权等,请点击“版权申诉”(推荐),也可以打举报电话:400-050-0827(电话支持时间:9:00-18:30)。
  4. 4、该文档为VIP文档,如果想要下载,成为VIP会员后,下载免费。
  5. 5、成为VIP后,下载本文档将扣除1次下载权益。下载后,不支持退款、换文档。如有疑问请联系我们
  6. 6、成为VIP后,您将拥有八大权益,权益包括:VIP文档下载权益、阅读免打扰、文档格式转换、高级专利检索、专属身份标志、高级客服、多端互通、版权登记。
  7. 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 的位数,这

文档评论(0)

ldj215322 + 关注
实名认证
文档贡献者

该用户很懒,什么也没介绍

1亿VIP精品文档

相关文档