题目
- 原文:
You are given two 32-bit numbers, M and N, and two bit positions, i and j. Write a method to set all bits between i and j in M equal to N (e.g., N becomes a substring of M located at i and starting at j).
EXAMPLE:
Input: M = 10000000000, N = 10101, i = 2, j = 6
Output: M = 10001010100 - 译文:
给定两个32位的数,M和N,还有两个指示位的数,i和j。 写程序使得M中第i位到第j的值与N中的相同(即:N变成M的位于第i位和第j位之间的子串)
例子:
输入: M = 10000000000, N = 10101, i = 2, j = 6
输出: M = 10001010100
分析
解题思路为:使得M的[i,j]位为0,其他位不变i,然后与左移i位后的N做或运算。
其中,使得M的[i,j]位为0有两种方法:
- 构造一个第i位到第j位为0,其他位为1的数temp,与M按位与【代码见bit_substr1()】;
- 先保留M的[0,i)位到temp,再使M的[0,j]位为0(通过先右移再左移j+1位),然后与temp做或运算【代码见bit_substr2()】。
代码
#include<iostream>
#include<vector>
using namespace std;
void print_binary(int n) {
vector<int> bitvec;
int mask = 1;
const int bit_len = 8;
int len = bit_len * sizeof(int);
while(len--) {
if(n & mask) {
bitvec.push_back(1);
}
else {
bitvec.push_back(0);
}
mask <<= 1;
}
while(!bitvec.empty()) {
cout << bitvec.back();
bitvec.pop_back();
}
cout << endl;
}
void bit_substr1(int &m, int n, int i, int j) {
//构造一个第i位到第j位为0,其他位为1的数temp
int a = (1 << i) - 1;
int b = ~((1 << (j+1)) - 1);
int temp = a | b;
//将temp与m按位与,使得m的第i位到第j位为0,其他位不变
m = m & temp;
//将m和左移i位后的n做或操作
m = m | (n << i);
}
void bit_substr2(int &m, int n, int i, int j) {
//保留m中的[0,i)位到(其他位为0)temp
int temp = m & ((1<<i) - 1);
//使得m的[0,j]位为0,其他位不变
m = m >> (j+1);
m = m << (j+1);
//将m和左移i位后的n和temp做或操作
m = m | temp | (n << i);
}
int main() {
int a = 1 << 10;
cout << " m is: ";
print_binary(a);
int b = 21;
cout << " n is: ";
print_binary(b);
//bit_substr1(a, b, 2, 6);
bit_substr2(a, b, 2, 6);
cout << "new m is: ";
print_binary(a);
b = 15;
cout << "new n is: ";
print_binary(b);
//bit_substr1(a, b, 4, 7);
bit_substr2(a, b, 4, 7);
cout << "now m is: ";
print_binary(a);
}
结果
位运算补充
有符号整型int和无符号整型unsigned int 右移对比:(前者正数补0负数补1,后者通通补0,左移两者都补0)
#include<iostream>
#import<cmath>
using namespace std;
int main() {
//整型
int t = -2;
cout << " -2 is:";
print_binary(t);
cout << "-2右移一位是:";
print_binary(t >> 1);
cout << "-2右移一位是:" << (t >> 1) << endl;
//无符号整型
unsigned int ut = pow(2,32) - 2;
cout << " " << ut << " is:";
print_binary(ut);
cout << ut << "右移一位是:";
print_binary(ut >> 1);
cout << ut << "右移一位是:" << (ut >> 1) << endl;
}