这是在C++博客园写的。希望和大家一起努力。
摘自:http://www.cppblog.com/Springsnow/
这也是《程序员面试攻略》上的一道题,题目是这样的:
请编写一个函数,确定一个整数的计算机内部表示中有几个“1”。
思索了一下这个题目,我是这样考虑的,也学书上给出伪代码
count = 0;
while (这个整数不为0)
{
如果这个整数对2求余的结果是1,则count加1;
将这个整数向右移移位
}
代码写出来是这样的:
![](https://i-blog.csdnimg.cn/blog_migrate/cbef093dcc044b2793832001e2365e43.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/2f88ce130b654eb5dc6788e02dbcfc90.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/df37983f39daa189b8c814e01a6a9011.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/df37983f39daa189b8c814e01a6a9011.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/f70a0fde2b51b7dd92a70e712e540cf6.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/df37983f39daa189b8c814e01a6a9011.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/df37983f39daa189b8c814e01a6a9011.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/df37983f39daa189b8c814e01a6a9011.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/4a5daaec04350a363f186a4d2c5ed6ce.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/df37983f39daa189b8c814e01a6a9011.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/df37983f39daa189b8c814e01a6a9011.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/0ac3a2d53663ec01c7f7225264eeefae.gif)
看了一下书中的答案,的确比我简练很多。对于求余这个方法还是比较笨的。书中采用了逻辑与。
判断条件从“num%2 == 1”变成 “num&1 == 1”,从程序中更倾向与后者。
所以在分析问题的时候,要学会用逻辑“与、或、异或”进行判断。
到这一步,看似已经很完美了。但是书中又出奇的给了另一种解法。这种想法我真的没有想到。
想法的出发点是考虑一个数字减1时,它的二进制发生了什么变化。减1得到的结果是,从最低位的1到最低位都发生了翻转,其他高位保持不变。如果您对这个整数和减一后的结果进行AND操作,得到的新的数字与原来的整数相比,只有最后一个1变成0.
如果进行多次这样的操作,这个整数的值变为0。这样我们也就获得了这个数的计算机表示中“1”的个数。
![](https://i-blog.csdnimg.cn/blog_migrate/cbef093dcc044b2793832001e2365e43.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/2f88ce130b654eb5dc6788e02dbcfc90.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/df37983f39daa189b8c814e01a6a9011.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/df37983f39daa189b8c814e01a6a9011.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/f70a0fde2b51b7dd92a70e712e540cf6.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/df37983f39daa189b8c814e01a6a9011.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/df37983f39daa189b8c814e01a6a9011.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/4a5daaec04350a363f186a4d2c5ed6ce.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/df37983f39daa189b8c814e01a6a9011.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/0ac3a2d53663ec01c7f7225264eeefae.gif)
第一方法的时间复杂度为o(n),第二种的时间复杂度为o(m),m为1的个数。
后记:
最近一周多,一直在做这本书上的编程题。一天3道,自己先尝试编写,运行成功后再与书上的解答进行对比。稍有几次略感比书上稍好些。但大多数情况还是效率差一些。想想原因,还是练得比较少。所以继续努力。多多积累,养成良好的思维习惯。