积跬步至千里——算法强化训练(4)位操作的几个实例
2015-05-16 20:58
176 查看
1.利用位运算统计二进制中1的个数
2.利用位运算做加法
如果不考虑进位,两个二进制的相加,便是两个数异或,但是如果存在进位,则结果还要和进位在异或,直到没有进位为止。以5(101)加上17(10001)为例 第一步 10100 但是有进位(00001<<1) 第二步 10100和00010异或 10110 无进位,则结果10110(22)
3.其它用处
比如交换两个数 找出一组数中唯一出现的数字 唯一出现的两个数字等等题目
一个数组中,只有两个数字各出现1次,其它都出现两次
思路:我们知道,两个相同的数字异或结果为0,0与其他数异或等于其他数,那么这组数字异或的结果等于这两个只出现1次的两个数异或,分析这个结果,这个结果的二进制表示中从右往左肯定有一位不为零,则这两个数字一个和结果一样这一位不为零,另一个这一位为零。即选出数字
int NumberOfOne(int n) { int cnt = 0; for (;n>0;n=n>>1) if(n & 0x1) cnt++; return cnt; }
int NumberOfOne2(int n) { int cnt = 0; while (n) { cnt++; n = n & (n-1); } return cnt; }
2.利用位运算做加法
如果不考虑进位,两个二进制的相加,便是两个数异或,但是如果存在进位,则结果还要和进位在异或,直到没有进位为止。以5(101)加上17(10001)为例 第一步 10100 但是有进位(00001<<1) 第二步 10100和00010异或 10110 无进位,则结果10110(22)
int Add(int a,int b) { int sum,carry; do { sum = a ^ b; carry = (a & b)<<1; a = sum; b = carry; } while (b!=0); return a; }
3.其它用处
比如交换两个数 找出一组数中唯一出现的数字 唯一出现的两个数字等等题目
一个数组中,只有两个数字各出现1次,其它都出现两次
思路:我们知道,两个相同的数字异或结果为0,0与其他数异或等于其他数,那么这组数字异或的结果等于这两个只出现1次的两个数异或,分析这个结果,这个结果的二进制表示中从右往左肯定有一位不为零,则这两个数字一个和结果一样这一位不为零,另一个这一位为零。即选出数字
void FindTheTwo(vector<int> &data) { int len = data.size(); int temp = 0,i,j ; int answer1 = 0, answer2 = 0; for (i = 0; i < len; ++i) temp = temp ^ data[i]; for (j = 0; j < 32; ++j)//找到temp中不为零的位置 if(temp>>j && 0x1 == 1) break; for (i = 0; i < len; ++i) { if(data[i]>>j & 0x1) answer1 ^= data[i]; else answer2 ^= data[i]; } cout<<"The Two Numbers are "<<answer1<<" "<<answer2<<endl; }
相关文章推荐
- 积跬步至千里——算法强化训练(5)关于类的几个操作
- 积跬步至千里——算法强化训练(3)数组装水
- 积跬步至千里——算法强化训练(1)统计数组中的逆序对
- 积跬步至千里——算法强化训练(6)利用基数排序解决O(n)问题
- 积跬步至千里——算法强化训练(9)重写标准库函数
- 积跬步至千里——算法强化训练(8)卡特兰数相关题目求解
- 积跬步至千里——算法强化训练(2)全排列和组合数
- 积跬步至千里——算法强化训练(7)大数问题
- 几个最短路径算法Floyd、Dijkstra、Bellman-Ford、SPFA的比较
- 重新认识java(零) --- 不积跬步无以至千里
- jquery几个实例图片轮播等
- 关于scanf的算法(位操作)
- 深入理解PHP几个算法:PHP冒泡、PHP二分法、PHP求素数、PHP乘法表
- LINUX服务器几个简单修改文件权限的命令实例
- Oracle的几个概念:数据库名,全局数据库名,SID,实例,命名空间,schema
- 位操作在算法中的运用
- 实例介绍删除数据库中重复数据的几个方法
- set,bitset 的一个应用实例——数据结构和比较算法
- HMM学习笔记_2(从一个实例中学习HMM前向算法)
- 算法:动态规划——区间模型之最少添加几个字符使得字符串变成回文串