位运算专题(个人理解)

简介: 位运算专题(个人理解)

Acwing 位运算专题


位运算介绍


什么是位运算呢?位运算就是二进制数据进行运算的运算符,这里我们主要说到左移,右移,按位与,按位或,按位取反,异或。

1.左移<<
1010<<1
1010左移一位后:10100
即向左移动,低位补0
2.右移>>
1010右移一位后:0101
各二进位全部右移若干位,对无符号数,高位补0,有符号数,右移补1
3.按位与&
按位与与代码中的逻辑运算从差不多,两个都是1才是1,否则是0
如:1 0 1 0
  & 1 1 0 0
  ————————————
    1 0 0 0
4.按位或|
按位或和我们代码中加的逻辑运算差不多,在对两个二进制数进行或运算时,只要其中一个有1,那么就是1,两个都为0才是0
如:1 0 1 0
 |  0 1 1 0
 _____________
    1 1 1 0
5.按位取反~
1变0,0变1
如:~1010
取反后:0101
6.异或
相同为零,不同为1
如:  1 0 1 0 0 1
  ^   1 1 0 0 1 0
    _______________
      0 1 1 0 1 1


小技巧:


去掉最后一位
x>>1
在最后一位加个0
x<<1
在最后一位加个1
(x<<1)|1
把最后一位变成1
x|1
把最后一位变成0
(x|1)-1
最后一位取反
x^1
把右数第k为变成1
x|(1<<(k-1))
解释:将1向左移动k-1位,第k位是1,1到k-1位是0
吧右数第k位变成0
x&(~(1<<(k-1)))
解释:1向左移动k-1位,第k位是1,1到k-1位是0,取反后在与


位运算符优先级比较靠后,结合使用时一般需加上括号


例1 .不用加减乘除做加法

写一个函数,求两个整数之和,要求在函数体内不得使用 +、-、×、÷+、-、×、÷ 四则运算符号。


数据范围


−1000≤num1,num2≤1000−1000≤num1,num2≤1000


样例


1. 输入:num1 = 1 , num2 = 2
2. 
3. 输出:3
// 1100
// 1010
//10110
class Solution {
public:
    int add(int num1, int num2)
    {
        int a,b;
        a=num1^num2;//将不进位的相加
        b=(num1&num2)<<1;//将进位的相加
        return a+b;
    }
};


例二 将 x 的二进制表示中第 i 位和第 j 位的值互换,并输出互换后的结果

给定一个正整数 xx,请你将 xx 的二进制表示中第 ii 位和第 jj 位的值互换,并输出互换后的结果。

注意: xx 的二进制表示的最右边为第 00 位。


输入格式


共一行,包含三个整数 x,i,j


输出格式


一个整数,表示互换后的结果。


数据范围


1≤x≤2^31−11≤x≤2^31−1,

0≤i,j≤30.


输入样例1:


38 2 4


输出样例1:


50


输入样例2:


1 0 2


输出样例2:


4


分四种情况:

1. 两个位置均为1

2.两个位置均为0

3.一个位置为1,一个位置为0

4.一个位置为0,一个位置为1

1和2两种情况不需要做处理

AC代码:

#include<bits/stdc++.h>
using namespace std;
int main()
{
  int m,a,b,result;
  cin>>m>>a>>b;
  result=m;
  int i=m>>a&1;
  int j=m>>b&1;
  if(i&&!j)
  result=m-(1<<a)+(1<<b);//减去原有位置上1的值加上变化后1位置的值
  if(!i&&j)
  result=m+(1<<a)-(1<<b);//加上原有位置上1的值减去变化后1位置的值
  cout<<result<<endl;
  return 0; 
}


例三 数组中只出现一次的两个数字


一个整型数组里除了两个数字之外,其他的数字都出现了两次。


请写程序找出这两个只出现一次的数字。


你可以假设这两个数字一定存在。


数据范围


数组长度 [1,1000][1,1000]。


样例


1. 输入:[1,2,3,3,4,4]
2. 
3. 输出:[1,2]


AC代码:


class Solution {
public:
    vector<int> findNumsAppearOnce(vector<int>& nums) 
    {
        int m=1,n,j=0,x=0,y=0;
        n=nums.size();
        for(int i=0;i<n;i++)//先遍历异或得出x异或y的值
        {
            j^=nums[i];
        }
        while((j&m)==0)//找出第一个x和y不相等的二进制位
        {
            m<<=1;
        }
        for(int i=0;i<n;i++)
        {
            if(nums[i]&m)//将含x和含y的分为两组
            x^=nums[i];
            else
            y^=nums[i];
        }//最终异或出来的两数即为x和y的值
        return vector<int>{x,y};
    }
};

目录
相关文章
|
6月前
玩转位运算
玩转位运算
|
存储 Java
一篇搞定位运算(&、|、^、~、>>、<<、>>>)
我们最了解的就是十进制 , 除了十进制 , 还有二进制 , 六进制 , 八进制等等 , 由于位运算操作就是二进制 , 所以我们主要来说一下二进制 , 十进制的个位有(0~9)这几个数字 , 而二进制也相同 , 二进制的个位上只有0和1
58 0
|
1月前
|
机器学习/深度学习
位运算详解
本文介绍了位运算符及其基本操作,并通过几个例题详细解析了位运算的应用。内容包括左移`&lt;&lt;`、右移`&gt;&gt;`、按位取反`~`、与运算`&`、或运算`|`和异或运算`^`等运算符的使用方法。基本操作部分展示了如何检查和修改二进制位,以及异或运算的性质。例题部分则通过判定字符是否唯一、丢失的数字、两整数之和和消失的两个数字等问题,具体说明了位运算的实际应用技巧。
40 7
位运算详解
|
5月前
|
编译器 Linux C++
详细解读C++中的位运算总结
详细解读C++中的位运算总结
35 0
|
6月前
|
C++
位运算
位运算“【5月更文挑战第23天】”
40 1
|
5月前
|
机器学习/深度学习
常见位运算的总结
常见位运算的总结
46 0
|
存储 Java 程序员
“高端”的位运算
大家好,我是王有志。原计划迭代作为预备知识的收尾,不过在解2的幂和4的幂时,想到关于数字2的问题可以通过位运算去解决,因此补充了关于位运算的内容。
90 1
|
算法 Java 编译器
第 13 天_位运算
第 13 天_位运算
90 0
|
算法 数据安全/隐私保护
基本的位运算
基本的位运算
|
算法
位运算能做什么
位运算能做什么
54 0