300字范文,内容丰富有趣,生活中的好帮手!
300字范文 > 【编程之美】2.1求二进制中1的个数

【编程之美】2.1求二进制中1的个数

时间:2023-11-27 13:28:26

相关推荐

【编程之美】2.1求二进制中1的个数

数据库|mysql教程

编程,之美,2.1,二进制,个数,题目,对于,一个,字节,无

数据库-mysql教程

教学信息管理系统的源码,ubuntu关闭下载密码,网络爬虫 评估词表,全景 php源码,萧县企业seolzw

题目: 对于一个字节的无符号整数变量,求其中的二进制表示中1的个数,要求算法执行效率尽可能高效。 题目解析: 这道题同样在【剑指offer】面试题10:二进制中1的个数中出现,不过在剑指offer中没有提到无符号数,因此比该题目中多考虑一个层次。下面总结这

ckfinder 2.3源码,ubuntu重置密码命令,tomcat9的性能,电话邦爬虫,php erp开发,阜南县seo关键词优化lzw

discuz内核源码,用vscode编译go,如何复制ubuntu,怎么添加tomcat插件,华为手机sqlite数据库,通体大红色的小爬虫有哪些,php发送带附件邮件,东莞seo营销哪家好,电子商务网站源码下载,asp网站模板免费下载lzw

题目:

对于一个字节的无符号整数变量,求其中的二进制表示中1的个数,要求算法执行效率尽可能高效。

题目解析:

这道题同样在【剑指offer】面试题10:二进制中1的个数 中出现,不过在剑指offer中没有提到无符号数,因此比该题目中多考虑一个层次。下面总结这道题的几种解法。

解法一(用于该题目):

我们通常会想到除以2就是将二进制右移一位,但要判断移除的是0还是1,就要对2取余。思路很简单,通过四则运算来解答:

int Count(Byte v){ int num = 0; while(v){ if(v%2) num++; v /= 2; } return num;}

解法二(用于该题目):

对于除以2来表示二进制右移,除法的效率比直接移位的效率低得多。碰到这样的题目,尽量用移位来代替。位运算就五种形式:与、或、异或、左移和右移。在这些范围里面找到自己想要的运算。移位时要判断移除的是0还是1,那么这里就应该通过与操作判断最后一位是否为1。

int Count2(Byte v){ int num = 0; while(v){ if(v & 1) num++; //也可以用 num += v&1; 来代替上面两行 v = v >> 1; } return num;}

解法三(可以用于有符号数):

如果这个题目是有符号的话,当右移的时候,会在高位补充符号位,用上面两种方法的话,会陷入死循环。如何避免?可以先判断最高位,然后遍历n-1次判断除了最高位以外的位是否为1。这样的方法比较麻烦。我们可以变通一个思路,让与的那一位1不断的左移,直到将1移到最高位。

int Count3(Byte v){ int num = 0; int flag = 1; while(flag){ if(v & flag) ++num; flag = flag << 1; } return num;}

解法四(更加高效的算法):

这种方法,充分利用了二进制的相关操作,平时应该多收集这样的运算。

一个数不为0,那么二进制中肯定含1。当让这个数减去1时,最低位的1由1->0,更低位的0由0->1。当让n与n-1相与以后,n中最低位的1变成0。一次这样的操作,消去一个1,那么二进制中有多少个1,就循环多少次即可。

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

解法五(空间换时间方法):

其实方法四已经够好了,但是因为只涉及到八位,我们可以利用选择直接选取相应的数据。比如0x1-0x2-0x4…这些都包含1个1;0x3-0x6…包含两个1;等等。通过switch语句选择相应的结果。但是这种方法效率可能比较低,因为,当输入v为255的时候,得比较到最后才能找到相应的数据。

int Count5(Byte v){ int num = 0; switch(v){ case 0x0: num = 0; break; case 0x1: case 0x2: .... } return num;}

解法六(哈希表法):

既然想到了利用空间换时间,我们干脆用个数组来表示,index为要查找的数,counttable[index]为该数据包含1的个数。

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。