位运算面试题总结
来源:互联网 发布:阿里云服务器个人 编辑:程序博客网 时间:2024/05/17 07:11
更新二进制位
题目链接http://www.lintcode.com/zh-cn/problem/update-bits/
题目描述
给出两个32位的整数N和M,以及两个二进制位的位置i和j。写一个方法来使得N中的第i到j位等于M(M会是N中从第i为开始到第j位的子串)
样例
N = (10000000000)2,M = (10101)2, i = 2, j = 6返回N = (10001010100)2
class Solution {public: /** *@param n, m: Two integer *@param i, j: Two bit positions *return: An integer */ int updateBits(int n, int m, int i, int j) { // write your code here,位数从0开始. unsigned int mask; /* 如果j<31,将i到j位清0,利用((1<<(j+1))-(1<<i))得到i~j之间全是1的数,再取反; 如果j=32,i~最高位全部清0,(1<<i)-1可得到i~最高位之间全是0,其他位为0的数; */ if(j < 31) { //方法1 //mask = ~((1 << (j+1)) - (1 << i)); //方法2 mask = ~((((0xFFFFFFFF) << (31 - j)) >> (31 - j + i)) << i); } else mask = (1 << i) - 1; return (m << i) + (n & mask); }};
A + B问题
题目链接http://www.lintcode.com/zh-cn/problem/a-b-problem/
题目描述:给出两个整数a和b, 求他们的和, 但不能使用 + 等数学运算符。
主要利用异或运算来完成
异或运算有一个别名叫做:不进位加法,那么a ^ b就是a和b相加之后,该进位的地方不进位的结果,然后下面考虑哪些地方要进位,自然是a和b里都是1的地方,a & b就是a和b里都是1的那些位置,a & b << 1 就是进位之后的结果。所以:a + b = (a ^ b) + (a & b << 1),令a’ = a ^ b, b’ = (a & b) << 1,可以知道,这个过程是在模拟加法的运算过程,进位不可能一直持续,所以b最终会变为0。
class Solution {public: /* * @param a: The first integer * @param b: The second integer * @return: The sum of a and b */ int aplusb(int a, int b) { // write your code here, try to do it without arithmetic operators. while (b != 0) { int c = a & b; a = a ^ b; b = c << 1; //cout<<a<<b<<endl; } return a; }};
检验整数n是不是2的幂数
题目链接http://www.lintcode.com/zh-cn/problem/o1-check-power-of-2/
如果n是2的幂数
- n > 0
- n的二进制数中只有一个1
class Solution {public: /* * @param n: An integer * @return: True or false */ bool checkPowerOf2(int n) { // write your code here,考虑特殊情况0和最小负数 return n > 0 && ((n & (n - 1)) == 0); }};
计算在一个 32 位的整数的二进制表式中有多少个 1
题目链接http://www.lintcode.com/zh-cn/problem/count-1-in-binary/
由x & (x - 1)消去x最后一位的1可知。不断使用 x & (x - 1) 消去x最后一位的1,计算总共消去了多少次即可。
class Solution {public: /** * @param num: an integer * @return: an integer, the number of ones in num */ int countOnes(int num) { // write your code here unsigned int n = (unsigned int)num; int times = 0; while(n) { n = n & (n - 1); times++; } return times; }};
如果要将整数A转换为B,需要改变多少个bit位?
题目链接http://www.lintcode.com/zh-cn/problem/flip-bits/
可以转化为A^B中1的个数
class Solution {public: /** *@param a, b: Two integer *return: An integer */ int bitSwapRequired(int a, int b) { // write your code here int c = a ^ b; int ret = 0; while (c) { ret += 1; //cout<<c<<endl; c = c & (c - 1); } return ret; }};
数组中,只有一个数出现一次,剩下都出现两次,找出出现一次的数
题目链接http://www.lintcode.com/en/problem/single-number/
利用 a ^ b ^ b = a
class Solution {public: /** * @param A: Array of integers. * return: The single number. */ int singleNumber(vector<int> &A) { // write your code here int size = A.size(); if (size == 0) { return 0; } int ret = A[0]; for (int i = 1; i< size; i++) { ret = ret ^ A[i]; } return ret; }};
数组中,只有一个数出现一次,剩下都出现三次,找出出现一次的数
题目链接http://www.lintcode.com/zh-cn/problem/single-number-ii/
class Solution {public: /** * @param A : An integer array * @return : An integer */ int singleNumberII(vector<int> &A) { // write your code here int size = A.size(); int times[32] = {0};//统计每一位中1的个数 for (int i = 0; i < size; i++) { for (int j = 0; j < 32; j++) { if ((A[i] & (1 << j)) > 0) { times[j] += 1; times[j] %= 3;//防止越界 } } } int ret = 0; for (int i = 31; i >= 0; i--) { ret = ret << 1; ret += times[i]; } return ret; }};
数组中,只有两个数出现一次,剩下都出现两次,找出出现一次的数
题目链接http://www.lintcode.com/zh-cn/problem/single-number-iii/
求二进制中最后一位1的个数
原码,二进制表示
反码,正数的反码就是原码,负数的反码是符号位不变,其余位取反
补码,正数的补码就是原码,负数的补码是反码 + 1
在计算机中都是采用补码的形式存储
所以,a&-a就是a最后一位1的位置
不妨假设出现一个的两个元素是x,y,那么最终所有的元素异或的结果就是res = x^y。并且res!=0,那么我们可以找出res二进制表示中的某一位是1。对于原来的数组,我们可以根据这个位置是不是1就可以将数组分成两个部分。x,y在不同的两个子数组中。而且对于其他成对出现的元素,要么在x所在的那个数组,要么在y所在的那个数组。
class Solution {public: /** * @param A : An integer array * @return : Two integers */ vector<int> singleNumberIII(vector<int> &A) { // write your code here int size = A.size(); vector<int> ret = {0,0}; if (size == 0) { return ret; } int diff = A[0]; for (int i = 1; i < size; i++) { diff ^= A[i]; } diff &= -diff; for (int i = 0; i < size; i++) { if ((A[i] & diff) == 0) { ret[0] ^= A[i]; } else { ret[1] ^= A[i]; } } return ret; }};
%3
给一个很长的二进制字符串,计算除以3的余数
奇数位除以3余1,偶数位除以3余2,所以
- 奇数位1的个数等于偶数位1的个数,则余数为0
- 奇数位个数大于偶数位,个数相减后 %3
- 偶数位个数大于奇数位,个数相减后*2%3
int fun(char* s, int len) { if (s == NULL) return 0; int odd_num = 0; int even_num = 0; int times = 1; for(int i = len - 1; i>=0; i--) { if(s[i] == '1') { if(times & 1) odd_num++; else even_num++; } times++; } if(odd_num > even_num) return (odd_num-even_num)%3; else return (odd_num - even_num) * 2 % 3;}int main(){ char a[] = "10010001101000101011001111000"; cout <<fun(a,sizeof(a) - 1);}
- 位运算面试题总结
- 位运算面试题总结
- 位运算总结—各大公司笔试面试题
- 位运算总结—各大公司笔试面试题
- 面试题中的位运算
- 【面试题-J2SE】位运算
- 位运算相关面试题
- 位运算常见面试题
- 用位运算的一些面试题
- [经典面试题]位运算操作
- java面试题三 位运算符
- 位运算及相关面试题汇总
- 栈、队列、位运算面试题
- 位运算相关高频面试题
- 位运算面试题常用技巧
- 利用位运算实现四则运算 -- 华为面试题
- C语言面试题——位运算
- 两个与位运算有关的小问题【面试题】
- .NET入行之工作前
- 后代选择器
- 2——进程间的通信(通讯手段)
- uva10562
- 【思想感悟】你一定要在一个优秀的环境里
- 位运算面试题总结
- Android Launcher 之源码下载
- 50 years, 50 colors HDU
- Ehome:QT项目移植的开发环境与移植流程
- 微信公众号的分类
- 子元素选择器
- 使用Zeromq和protobuf实现的socket通信
- BitMap(位图)结构的C++实现
- 奇妙的异或