基础知识
位操作(Bit Manipulation)是程序设计中对位模式或二进制数的一元和二元操作。在现代架构中,位运算的运算速度通常与加法运算相同,快于乘法运算。
位操作包括:
-
& 按位与(AND) : 两个位都为1时,结果才为1
-
| 按位或(OR) : 两个位都为0时,结果才为0
-
~ 取反(NOT):0变1,1变0
-
^ 按位异或(XOR): 两个位相同为0,相异为1
-
移位 <<(左移), >>(右移):移位是一个二元运算符,用来将一个二进制数中的每一位全部都向一个方向移动指定位,溢出的部分将被舍弃,而空缺的部分填入一定的值。
移位又分为- 算术移位
- 逻辑移位
面试题一
面试题 插入
插入。给定两个32位的整数N与M,以及表示比特位置的i与j。编写一种方法,将M插入N,使得M从N的第j位开始,到第i位结束。假定从j位到i位足以容纳M,也即若M = 10 011,那么j和i之间至少可容纳5个位。例如,不可能出现j = 3和i = 2的情况,因为第3位和第2位之间放不下M。
代码:
class Solution {
public:
int insertBits(int N, int M, int i, int j) {
//把N中i,j位清为0
for(int k = i;k <= j;k++) {
if(N & 1 << k)
N -= (1 << k);
}
//将处理后的N加上M
return N + (M << i);
}
};
面试题二
翻转数位:给定一个32位整数 num,你可以将一个数位从0变为1。请编写一个程序,找出你能够获得的最长的一串1的长度。
class Solution {
public:
/*
采用状压常用操作,把一个数x右起第一个0变为1只需要x|(x+1)即可,然后数一下右起的1的个数,
更新一下答案,然后把原来的x右边连续的1去掉,继续下去即可,特判一下0以及开long long就好了)。
*/
int count1(long long num) {
int ans = 0;
while(num & 1) {
++ans;
num >>= 1;
}
return ans;
}
int reverseBits(long long num) {
if(num == 0)
return 1;
int cnt = 1;
while(num) {
cnt = max(cnt,count1(num | num + 1));
int t = count1(num);
num >>=( t + 1);
}
return cnt;
}
};