计算出二进制数中有多少个1
来源:互联网 发布:新型网络搜索引擎 编辑:程序博客网 时间:2024/04/30 12:33
《编程之美》这本书被很多计算机专业的学生奉为面试经典, 其中也包括我。早就听高年级学长说过,面试中的题目有80%取自《编程之美》这本书, 掌握了其中的全部算法可以为自己的面试带来很多的好处。从今天起, 我每天更新编程之美上的一个算法, 方便想要学习的童鞋学习。
计算机专业的学生对二进制数应该都不陌生, 二进制就是由连续的有穷的0,1序列组成的数。那么, 我们的问题就来了, 现在我要统计一个01序列中有多少个1。那么, 我们应该怎么求解呢?
解法1:普通的解法,二进制数中相邻的两个数位在十进制书中参在2倍的关系。那么,我们的算法就出来了, 不断的对目标十进制数取余, 如果v%2==1, 那么证明当前的对应的二进制数位的数值为1;否则为0。算法如下:
int count(int v)
{
int number = 0;
while(v)
{
if(v%2 == 1)
{
number++;
}
v /= 2;
}
return number;
}
学过算法的同学应该不难分析出来,算法的复杂性是O(logv)。
解法2:根据上述的算法, 我们发现上诉程序的收敛过程是目标数不断的除以2。我们知道,在计算机在运算的时候,对于除法的计算异常的复杂,所以在这里我们采用位运算。算法如下:
int count(long v)
{
int number = 0;
while(v)
{
if(v%2 == 1)
{
number++;
}
v >>= 1;
}
return number;
}
在这里, 我们在收敛过程中使用了位运算,提高了运行的速度。但是,因为算法本身没有发生变化,所以时间复杂度为O(logv)。
解法3:在上述的算法中, 我们的知道, 算法的复杂度就是二进制数的长度,从某种意义上讲,我们对二进制进行了一个遍历。从而得到了我们的算法和分析。但是有没有更好的?在《编程之美》中 , 书中提供了一种更为快捷的算法, 时间复杂度是O(二进制数中1的个数)。
那么,写这本书的大神是怎么想出来的呢?我想思路主要有以下的几点:
(1)从算法的最有复杂度考虑:算法的最优的复杂度当然是O(1),但是这道题显然不能, 所以我们想到了下一个算法复杂度O(logN),这个复杂度是我们第一个解和第二个解的复杂度, 所以我们立马想到, 再优的算法当然就是在O(m)(m为二进制中的1的个数).
(2)有了上面的分析, 那么我们就要构造出这个算法。想要达到这个算法复杂度, 我们就必须对二进制数进行必要剪枝,所谓剪枝就是减去掉二进制数中的0。那么怎么去掉呢?我们来分析以下二进制的构成:
0x1100010101000
在上诉这个二进制数, 我们可以看到0,1交替出现,当我们用这个数减去一个1的时候, 我们发现最这个数最大的影响就是这个数的最后一一个1变为了0, 并且这个1后面全部的0变为了1, 于是我们可以想到对数进行“与”操作, 去掉受影响的部分,这样下去直到整个目标数变为0.算法复杂度还真就达到了上述的目标复杂度。
算法如下:
int count(long v)
{
int number = 0;
while(v)
{
v &= (v-1);
number++;
}
return number;
}
呵呵, 是不是很爽, 算法的魅力就在这里,我们可以用各种稀奇古怪的东西对计算的过程进行一系列的优化。
- 计算出二进制数中有多少个1
- 统计32位二进制数中有多少个1
- c/C++ 求一个二进制数中有多少个1
- _builtin_popcount()计算二进制中多少个1
- 计算二进制数有多少个‘1’
- 二进制序列有多少个1
- 题目:二进制中有多少个1
- 二进制中有多少个1
- 容易 二进制中有多少个1
- 二进制中有多少个1
- 二进制中有多少个1-lintcode
- 二进制中有多少个1
- 二进制中有多少个1
- 二进制中有多少个1
- 二进制中有多少个1
- _builtin_popcount()计算二进制中多少个1
- Lintcode 二进制中有多少个1
- 二进制中有多少个1
- 嵌入式Linux下基于FFmpeg的视频硬件编解码
- GeoServer+OpenLayers发布下载的Google卫星影像
- Axis-1.1 webService实现跨project传递参数入
- 一个游戏程序员的学习资料
- 在vs2010+MFC中动态添加菜单选项
- 计算出二进制数中有多少个1
- 第九周实验报告2
- VPN
- 宏定义之“#”
- 4秒100万条数据导入SQL数据库
- [php笔记]session
- 第九周实验报告1
- cglib动态代理介绍
- jquery实现弹出层的动画效果,相对定位