位运算相关题目
Posted ych9527
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了位运算相关题目相关的知识,希望对你有一定的参考价值。
插入
给定两个整型数字 N 与 M,以及表示比特位置的 i 与 j(i <= j,且从 0 位开始计算)。编写一种方法,使 M 对应的二进制数字插入 N 对应的二进制数字的第 i ~ j 位区域,不足之处用 0 补齐。具体插入过程如图所示。
题解:
1.将N的 i-j位置为0,即用N减去N当前位置的值
2.将M左移i位,即将M的最后一位挪到i的位置
3.将两个数相加
class Solution {
public:
int insertBits(int N, int M, int i, int j) {
//将N的 i-j位置为0
for(int k=i;k<=j;k++)
{
int num=N&(1<<k);//得到第K位的数为多大
N-=num;//减去这个数,就是将这个位置,置为0
}
return N + (M<<i);
}
};
整数转换
整数转换。编写一个函数,确定需要改变几个位才能将整数A转成整数B。
题解:
1.两个数进行按位与可以得到不同的位组成的值(注意负数,所以用无符号整形变量接收值)
2.求这个值中1的个数,即为需要改变的位数
3.num&(num-1) 即可去除这个数最后一个1
class Solution {
public:
int convertInteger(int A, int B) {
//得到A、B有多少个位不同,即最少需要改变几个位
//异或得到的位是不同的
unsigned num=A^B;
int count=0;
while(num)
{
num&=(num-1);
count++;
}
return count;
}
};
配对交换
配对交换。编写程序,交换某个整数的奇数位和偶数位,尽量使用较少的指令(也就是说,位0与位1交换,位2与位3交换,以此类推)。
题解:
1.首先得到奇偶位置的比特位
num&(1<<(i)) 不为0,则第i个位置的比特位为1,否则为0
2.比较奇偶位置的比特位,如果相反,则进行操作,否则不进行操作
将第i个位置设置为0:num-=(1<<i)
将第i个之为设置为1: num+=(1<<i)
class Solution {
public:
int exchangeBits(int num) {
//得到奇数和偶数的位置是0还是1
for(int i=0;i<31;i+=2)
{
int odd=num&(1<<(i+1));//得到奇数位
int even=num&(1<<i);//得到偶数位
if(odd==0&&even==0)//两个位置都为0
continue;
if(even!=0&&odd==0)//偶数位置为1,奇数位置为0
{
num-=even;//偶数位置变为0
num+=(1<<(i+1));//奇数位置变为1
}
else if(even==0&&odd!=0)//偶数位置为0,奇数位置为1
{
num+=(1<<i);//偶数位置变为1
num-=(1<<(i+1));//奇数位置变为0
}
}
return num;
}
};
下一个数
下一个数。给定一个正整数,找出与其二进制表达式中1的个数相同且大小最接近的那两个数(一个略大,一个略小)。
题解:
1.比特位个数相同,又正好大小最接近
2.接近 -> 改变的最少,并且比特位个数要相同
3.变大:将第一个为0的比特位变为1,在这个比特位后的第一个为1的比特位变为0,
然后将此位置后面的1全部挪到靠右边,0全部挪到靠左边
4.变小:将第一个为1的比特位变为0,将这个位置后面的第一个为0的比特位变为1
然后将此位置的后面的1全部挪到靠左边,0全部挪到靠右边
5.边界处理:找到的位置不能是符号位
class Solution {
public:
vector<int> findClosedNumbers(int num) {
//比特位个数相同,又正好大小最接近
//接近 -> 改变的最少,并且比特位个数要相同
//变大:将第一个为0的比特位变为1,在这个比特位后的第一个为1的比特位变为0,
//然后将此位置后面的1。全部挪到靠右边,0全部挪到靠左边
//变小:将第一个为1的比特位变为0,将这个位置后面的第一个为0的比特位变为1
//然后将此位置的后面的1全部挪到靠左边,0全部挪到靠右边
//边界处理:找到的位置不能是符号位
vector<int> ret(2,-1);
//1.获取num的比特位情况
vector<int> arr(32,0);
for(int i=0;i<32;i++)
{
if(num&(1<<i))//当前位不为0
arr[i]=1;
}
vector<int>max(arr);
//2.求变大的数
int end=-1;
for(int i=0;i<32;i++)
{
if(max[i]==0&&end!=-1&&i!=31)//找到第一个比特位为0的位置
{
max[i]=1;
max[end]=0;
break;
}
else if(max[i]==1)
{
end=i;
}
}
if(arr!=max)//没有找到
{
//统计 0-end位置1的个数
int count=0;
for(int i=0;i<end;i++)
{
if(max[i]==1)
count++;
}
//将所有的1挪到右边
for(int i=0;i<end;i++)
{
if(count!=0)
{
max[i]=1;
count--;
}
else
max[i]=0;
}
//取出比特位组成数字
int n_max=0;
for(int i=0;i<32;i++)
{
int n=max[i];
n_max|=(n<<i);
}
ret[0]=n_max;
}
//3.求变小的数
end=-1;
vector<int> min(arr);
for(int i=0;i<32;i++)
{
if(min[i]==1&&end!=-1&&i!=31)//找到第一个比特位为1的位置
{
min[i]=0;
min[end]=1;
break;
}
else if(min[i]==0)
{
end=i;
}
}
if(arr!=min)//没有找到
{
//统计 0-end位置0的个数
int count=0;
for(int i=0;i<end;i++)
{
if(min[i]==0)
count++;
}
//将所有的0挪到右边
for(int i=0;i<end;i++)
{
if(count!=0)
{
min[i]=0;
count--;
}
else
min[i]=1;
}
//取出比特位组成数字
int n_min=0;
for(int i=0;i<32;i++)
{
int n=min[i];
n_min|=(n<<i);
}
ret[1]=n_min;
}
return ret;
}
};
以上是关于位运算相关题目的主要内容,如果未能解决你的问题,请参考以下文章