BCZM : 2.1
1.问题描述
实现一个函数,输入一个无符号整数,输出该数二进制中的1的个数。例如把9表示成二进制是1001,有2位是1,因此如果输入9,该函数输出2
2.分析与解法
解法1:利用十进制和二进制相互转化的规则,依次除余操作的结果是否为1 代码如下:
int Count1(unsigned int v)
{
int num = 0;
while(v)
{
if(v % 2 == 1)
{
num++;
}
v = v/2;
}
return num;
}
解法2:向右移位操作同样可以达到相同的目的,唯一不同的是,移位之后如何来判断是否有1存在。对于这个问题,举例:10100001,在向右移位的过程中,我们会把最后一位丢弃,因此需要判断最后一位是否为1,这个需要与00000001进行位“与”操作,看结果是否为1,如果为1,则表示当前最后八位最后一位为1,否则为0,解法代码实现如下,时间复杂度为O(log2v)。
int Count2(unsigned int v)
{
unsigned int num = 0;
while(v)
{
num += v & 0x01;
v >>= 1;
}
return num;
}
解法3:利用"与"操作,不断清除n的二进制表示中最右边的1,同时累加计数器,直至n为0,这种方法速度比较快,其运算次数与输入n的大小无关,只与n中1的个数有关。如果n的二进制表示中有M个1,那么这个方法只需要循环k次即可,所以其时间复杂度O(M),代码实现如下:
int Count3(unsigned int v)
{
int num = 0;
while(v)
{
v &= (v-1);
num++;
}
return num;
}
编程之美同时给出了8bit的情况下,解法4:使用分支操作,解法5:查表法 再计算32bit无符号整数时,需要将32bit切为4部分 然后每部分分别运用解法4解法5下面仅给出代码:
解法4:
int Count4(unsigned int v)
{
int num = 0;
switch(v)
{
case 0x0:
num = 0;
break;
case 0x1:
case 0x2:
case 0x4:
case 0x8:
case 0x10:
case 0x20:
case 0x40:
case 0x80:
num = 1;
break;
case 0x3:
case 0x6:
case 0xc:
case 0x18:
case 0x30:
case 0x60:
case 0xc0:
num = 2;
break;
//.....
}
return num;
}
解法5:
unsigned int table[256] =
{
0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4,
1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5,
1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5,
2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5,
2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7,
1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5,
2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7,
2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7,
3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7,
4, 5, 5, 6, 5, 6, 6, 7, 5, 6, 6, 7, 6, 7, 7, 8
};
int CountTable(unsigned int v)
{
return table[v & 0xff] +
table[(v >> 8) & 0xff] +
table[(v >> 16) & 0xff] +
table[(v >> 24) & 0xff] ;
}
平行算法,思路:将v写成二进制形式,然后相邻位相加,重复这个过程,直到只剩下一位。以217(11011001)为例,有图有真相,下面的图足以说明一切了。217的二进制表示中有5个1。

代码如下:
int Count6(unsigned int v)
{
v = (v & 0x55555555) + ((v >> 1) & 0x55555555) ;
v = (v & 0x33333333) + ((v >> 2) & 0x33333333) ;
v = (v & 0x0f0f0f0f) + ((v >> 4) & 0x0f0f0f0f) ;
v = (v & 0x00ff00ff) + ((v >> 8) & 0x00ff00ff) ;
v = (v & 0x0000ffff) + ((v >> 16) & 0x0000ffff) ;
return v ;
}
求整数A和B的二进制表示中有多少位不同
首先A与B进行异或运算,结果M,计算M中含有的1的个数。
BCZM : 2.1的更多相关文章
- BCZM: Chapter 2
2.1 二进制数中 1 的个数 实现一个函数,输入一个无符号整数,输出该数二进制中的1的个数.例如把9表示成二进制是1001,有2位是1,因此如果输入9,该函数输出2 分析与解法 解法1:利用十进制和 ...
- BCZM: Chapter 1
1.1 CPU 占用率 https://www.cnblogs.com/TenosDoIt/p/3242910.html 1.2 中国象棋将帅 https://blog.csdn.net/kabini ...
- BCZM : 1.16
24点游戏 解法一:穷举法 解法二:分治法
- BCZM : 1.15
数独 解法一:广度优先搜索. 解法二:先填满中间矩阵,其他区域通过矩阵置换求出.
- BCZM : 1.9
有n个学生参加见面会,分别对m个研究组中的若干个感兴趣,为了满足所有学生的要求,每个学生都能参加自己感兴趣的见面会,如果每个见面会的时间为t,如何安排才能使得所有见面会的总时间最短? 分析: 先建立模 ...
- BCZM : 1.8
问题: 所有的员工均在1楼进电梯的时候,选择所要到达的楼层.然后计算出停靠的楼层i,当到达楼层i的时候,电梯停止.所有人走出电梯,步行到所在的楼层中.求所有人爬的楼层数目和的最小值. 解法一 ...
- BCZM : 1.7
光影切割 在一个平面内有一个矩形区域,直线穿过矩形可以将其分割为不同的区域,且在这个平面中不存在三条直线相交一点的情况.求当有N条直线穿过矩形时,它被分割为多少个区域? 解法一: 平面倍划分 ...
- BCZM : 1.6
https://blog.csdn.net/kabini/article/details/2311946 题目大意: 水房能容纳饮料的总量是V,有一批饮料,每种饮料单个容量都是2的方幂,每种饮料信息如 ...
- BCZM : 1.5
https://blog.csdn.net/zs634134578/article/details/18046317 有很多服务器存储数据,假设一个机器仅存储一个标号为ID的记录,假设机器总量在10亿 ...
随机推荐
- C/C++ 吐槽第一期:你最讨厌的C/C++里面的数据类型是什么
C/C++ 这里面讨论的范围包括从以往开始,到现有的所有官方标准,VC扩展,GCC扩展, C语言部分包括C89.C90.C99.C11这些知名的大版本,中间或者之前的比如K&R这种不出名的小版 ...
- 《构建之法》需求分析 读书笔记 Week6
本周选读<构建之法>第8章——需求分析.由于有团队项目初期调研阶段做调查问卷的经历,这一章节中很多知识点我都比较有体会.对我而言,这一章节最有价值的内容就是厘清了关于需求分析的两个误解和近 ...
- idae父子项目Test执行报Result Maps collection already contains value for xxx
现象:同一个springmvc工程使用eclipse和idea用Tomcat启动都没问题,但是如果走单元测试使用到了@ContextConfiguration这个spring的上下文注解idea出问题 ...
- vue+vue-cli2+webpack配置资源cdn
vue-cli2+webpack构建的vue项目如何让图片和js等静态资源走cdn,哪里可以配置呢?下面我详细介绍 1.config/index.js中可以看到 module.exports = { ...
- Java优化性能
尽量在合适的场合使用单例使用单例可以减轻加载的负担,缩短加载的时间,提高加载的效率,但并不是所有地方都适用于单例,简单来说,单例主要适用于以下三个方面:第一,控制资源的使用,通过线程同步来控制资源的并 ...
- goto和函数调用
goto: 函数调用: 作用域 label在函数内定义,所以函数内 跳转操作 无条件 调用时先保存现场,复制实际参数,然后才是跳转 生存期 由于不是左值,它没有生存期,仅在编译期有意义. ...
- 一个比较独特的"HelloWorld"
为什么说是特殊的helloworld呢给全世界的服务器发送一个请求,这就是我"打招呼"的方式核心内容就是:向所有的ipv4地址发送一个请求即x.x.x.x,如果其是web服务,就拿 ...
- java 多上传 CommonsMultipartFile[] files
/** * 视频上传 * ddl * @param request * @param response * @param files * @return * @throws Exception */@ ...
- js 获取数组中的最大值和最小值
var arr = [3,12,23,18,25,33,22,30,1] 方案一: 思想 首先对数组进行排序(小 >大),第一项为最小值,最后一项为最大值 var min; var max; a ...
- Spring源码剖析2:初探Spring IOC核心流程
本文转载自互联网,侵删 本系列文章将整理到我在GitHub上的<Java面试指南>仓库,更多精彩内容请到我的仓库里查看 https://github.com/h2pl/Java-Tutor ...