位运算相关题目:下一个数、整数转换、配对交换

题目1:下一个数

给定一个正整数,找出与其二进制表达式中1的个数相同且大小最接近的那两个数(一个略大,一个略小)。

示例:

 输入:num = 2(或者0b10)
 输出:[4, 1] 或者([0b100, 0b1])
 输入:num = 1
 输出:[2, -1]

解题思路:

1.先用bitset将num的32位二进制表示出来,存放到数组中,方便可以遍历

2.较大值:从左往右找到第一个01,将其转换成10,再将右侧剩余的1全都移动到最低位

eg.0101110   ->1000111

3.较小值:从左往右找到第一个10,将其转换成01, 再将右侧剩余的1全都移动到最高位

eg.1001110   ->0111100

4.bitset数组的下标是从低位开始的,也就是从右往左进行遍历

源代码如下:

class Solution {
public:
    vector<int> findClosedNumbers(int num) {
        bitset<32> smaller(num);//将二进制表示出来
        bitset<32> bigger(num);
        //找较小值
        int a=-1;//a初始化为-1
        for(int i=1;i<32;i++)
        {
            //找到10,变成01
            if(smaller[i]==1 && smaller[i-1]==0)
            {
                smaller.flip(i);//flip(i)将第i位上的数字进行翻转 (0转1,1转0)
                smaller.flip(i-1);
                //将右侧剩余的1,全移动到高位
                //相当于left和right的位互换
                for(int left=0,right=i-2;left<right;)
                {
                    //从低位找到第一个不为0的
                    while(left<right && smaller[left]==0) left++;
                    //从高位找到第一个不为1的
                    while(left<right && smaller[right]==1) right--;
                    //位翻转
                    smaller.flip(left);
                    smaller.flip(right);
                }
                //smaller.to_ulong()   将数组smaller转成unsigned long类型的值
                //再强转成int类型
                a=(int)smaller.to_ulong();
                break;
            }
        }
		//找较大值
        int b=-1;
        //在找较大值时,bigger要保证正数,最高符号位保证为0,最大正数为2147483647,2进制31个1,i只能到第30位,如果写 i<32 会出现上溢,所以这里与较小值不同的点在于要将i<32改为i<31,防止溢出
        for(int i=1;i<31;i++)
        {
            //找到01,变成10
            if(bigger[i]==0 && bigger[i-1]==1)
            {
                bigger.flip(i);
                bigger.flip(i-1);
                //将右侧剩余的1全移动到低位
                for(int left=0,right=i-2;left<right;)
                {
                    while(left<right && bigger[left]==1) left++;
                    while(left<right && bigger[right]==0) right--;
                    bigger.flip(left);
                    bigger.flip(right);
                }
                b=(int)bigger.to_ulong();
                break;
            }
        }
        return {b,a};
    }
};

题目2:整数转换

编写一个函数,确定需要改变几个位才能将整数A转成整数B。

示例:

 输入:A = 29 (或者0b11101), B = 15(或者0b01111)
 输出:2
 输入:A = 1,B = 2
 输出:2

 解题思路:

1.用bitset将整数A和B的32位 二进制表示出来存放在数组里,进行遍历

2.遇到aa[i]!=bb[i],说明需要转换,count++即可

源代码如下:

class Solution {
public:
    int convertInteger(int A, int B) {
        bitset<32> aa(A);//A的二进制
        bitset<32> bb(B);//B的二进制
        int i=0;//都是32位,所以只需要一个下标进行遍历
        int count=0;//用来记录需要改变的次数
        while(i<32)
        {
            //遇到当前位不相等的,就需要转换,count++
            if(aa[i]!=bb[i])
            {
                count++;
            }
            i++;
        }
        //返回count
        return count;
    }
};

题目3:配对交换

编写程序,交换某个整数的奇数位和偶数位,尽量使用较少的指令(也就是说,位0与位1交换,位2与位3交换,以此类推)。

示例:

 输入:num = 2(或者0b10)
 输出 1 (或者 0b01)

解题思路:

1.用bitset将num的二进制保存到数组中,便于用下标进行访问

2.从低到高两两进行交换,i+=2

3.将最后的结果用to_ulong()函数先转成unsigned long类型,再强转成int类型

源代码如下:

class Solution {
public:
    int exchangeBits(int num) {
        bitset<32> bit(num);
        int i=0;
        //从低到高进行两两交换
        //注意:因为要访问i+1,所以循环结束条件为i<31,防止越界
        while(i<31)
        {
            int temp=bit[i];
            bit[i]=bit[i+1];
            bit[i+1]=temp;
            i+=2;//i每次跳两个位数
        }
        //bit.to_ulong()  将二进制数转成unsigned long类型的值
        //再强转成int类型,就可以返回了
        return (int)bit.to_ulong();
    }
};
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值