给出两个32位的整数N和M,以及两个二进制位的位置i和j。写一个方法来使得N中的第i到j位等于M(M会是N中从第i为开始到第j位的子串)
普通的方法显然是将N的i到j位置0,然后与m<<i按位 | 即可。
这样需要操作 j - i 次。
考虑优化:
优化思路:想办法取得一个mask,其 第 i 位到 第 j 位为 0 ,其他位均为1。
使用两个mask: mask1 = 0x80000000, mask2 = 0xffffffff;
mask1 右移位左边补1,所以mask1>>(31-j-1) 之后,31到第j-1位均为1,第j位到第0位均为0;
mask2 左移位右边补0,所以 mask2<<i 之后,第i-1位到0位均为0,第i位到31位均为1;
mask1 与 mask2 异或操作的结果就是:i到j位均为1,其他位均为0;使用此mask即可求得最后结果
对 j==31 这个边界没想到什么好的方法统一处理,只能加个if 判断。
总共 7 次位操作取得最后结果,不知道还有没有更少的操作次数。
完整代码:
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
m <<= i;
int mask1 = 0x80000000, mask2 = 0xffffffff;
int mask;
if ( j == 31 ) {
mask = mask2<<i;
} else {
mask = ( mask1>>(31-j-1) ) ^ (mask2<<i) ;
}
return n & (~mask) | m ;
}
};