[编程之美] 2.1 求二进制数中1的个数
来源:互联网 发布:删除存储过程 sql 编辑:程序博客网 时间:2024/06/05 18:12
今天开始看《编程之美》了,这是一本评价很高的书,找工作当然少不了它。
部分题目已经在书中给出了答案,这里只是给出我的一些想法,有些也来源于此书,就当作做笔记吧。最后,感谢作者为我们奉献了一本优秀的程序员找工作宝典。
题目介绍:给定一个字节的无符号整型变量,求其二进制表示中“1”的个数,要求算法的执行尽可能高效。
因为题目要求算法尽可能高效,因此,对于书中的解法一大家应该不会考虑。不仅思路简单,而且其中用到的运算也很耗时,比如求余和除法。
大家最应该想到的应该就是解法二了,虽然思路同解法一一样,但使用了更为高效的位运算。
这里要提一下C++中的bitset,假如要求34的二进制表示中“1”的个数,可以这样来求:
bitset<8> b(34);cout << b.count() << endl;上面的代码声明了一个8位的bitset变量b,然后调用b的count()函数,它返回的就是这个bitset中被置位的个数。
代码很简洁,但是,如果细看count()函数的代码,就知道,它采用的就是最简单的方式:
size_tcount() const _GLIBCXX_NOEXCEPT{ return this->_M_do_count(); }size_t_M_do_count() const _GLIBCXX_NOEXCEPT{ size_t __result = 0; for (size_t __i = 0; __i < _Nw; __i++) __result += __builtin_popcountl(_M_w[__i]); return __result;}count()会调用_M_do_count(),_M_do_count()会依次检测它的所有位。因此,代码虽然简洁,但是效率并不高。
解法三的想法很好,前面的思路基本都是遍历这个整型变量的所有位,而解法三期望复杂度只与“1”的个数有关。
int Count(BYTE v){ int num = 0; while(v) { v &= v - 1; ++num; } return num;}v与v - 1进行与操作可以将v的最后一个“1”变成0,从而得到有1个“1”。这种方式还是很巧妙的。
至于解法四和解法五都采用了用空间换时间的策略,只不过解法五更加直接。
扩展问题:
1. 如果变量是32位的DWORD,你会使用上述的哪一个算法,或者改进哪一个算法?
解法一的时间复杂度是O(logN),也就是位数,而且使用了较慢的四则运算。
解法二的时间复杂度也是O(logN),但使用的是位运算,效率较第一种高。
解法三的时间复杂度是该数中“1”的个数,且使用位运算,效率更高。
解法四用的case分支语句,时间复杂度依赖于给定的数。
解法五很直接,时间复杂度为O(1)。
当位数较多时,肯定是解法三更好。如果位数较少的话,解法四和五也可以。这里是32位,用解法三。
2. 给定两个正整数A和B,把A变成B需要改变多少位?也就是说,整数A和B的二进制表示中有多少位是不同的?
将A和B异或,当对应的位不同时,结果为1,然后求结果中有多少个“1”就OK了。
- 编程之美---求二进制数中1的个数
- 《编程之美》:求二进制数中1的个数
- 【编程之美】求二进制数中1的个数
- 【编程之美】求二进制数中1的个数
- 编程之美---求二进制数中1的个数
- 编程之美---求二进制数中1的个数
- 《编程之美》 求二进制数中1的个数
- 读书笔记之编程之美 - 2.1 求二进制数中1的个数
- 编程之美: 第二章 数字之魅 2.1求二进制数中1的个数
- 编程之美 2.1 求一个数的二进制表示中1的个数
- 编程之美2.1 求二进制中1的个数
- 【编程之美】2.1求二进制中1的个数
- 编程之美2.1 求二进制中1的个数
- 编程之美 2.1 求二进制中1的个数
- 《编程之美》2.1 求二进制中1的个数
- 2.1《编程之美》读书笔记——“求二进制数中1的个数”
- 编程之美 2.1求二进制数中1的个数
- 《编程之美》2.1 求二进制数中1的个数(c++源代码)
- linux 进程间通信
- marquee 滚动
- 宣布与 NBC 合作直播索契冬季奥运
- Oracle必备语句 .
- Python字符串操作
- [编程之美] 2.1 求二进制数中1的个数
- 14.液晶LCD1602实验
- java反射机制
- ArrayList中toArray()方法的使用注意
- 中国网银安全分析:USB Key
- mysqldump使用常用参数说明
- jquery mobile的页面与对话框
- Mac修改环境变量
- 函数模板参数推导的两个经典应用