位运算专题(个人理解)

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

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};
    }
};

目录
相关文章
深入掌握ant-design的form异步校验(一)
本文适合对ant-design的表单校验感兴趣的小伙伴阅读~
|
Arthas 测试技术 网络安全
The telnet port 3658 is used by process
是否在本地使用Arthas的时候,遇到The telnet port 3658 is used by process 34725 instead of target process 44848, you will connect to an unexpected process的异常,其实解决方法很简单。
2415 0
The telnet port 3658 is used by process
|
8月前
|
消息中间件 存储 NoSQL
java连接redis和基础操作命令
通过以上内容,您可以掌握在Java中连接Redis以及进行基础操作的基本方法,进而在实际项目中灵活应用。
398 30
|
人工智能
[AI Mem0] 快速开始:智能记忆管理,让你的数据活起来!
[AI Mem0] 快速开始:智能记忆管理,让你的数据活起来!
|
8月前
|
人工智能 Java 程序员
HarmonyOS NEXT开发-ArkUI三
Image组件用于在应用中显示图片,支持png、jpg、bmp、svg和gif格式。加载本地或网络图片资源。常用属性包括`objectFit`,控制图片填充方式(Contain、Cover、Fill)。
108 0
HarmonyOS NEXT开发-ArkUI三
|
数据采集 SQL 关系型数据库
在 MySQL 中使用 ASCII
【8月更文挑战第11天】
314 1
在 MySQL 中使用 ASCII
|
安全 网络协议 Linux
Linux系统管理、服务器设置、安全、云数据中心
Linux系统管理、服务器设置、安全、云数据中心
|
数据采集 大数据 Python
FFmpeg 在爬虫中的应用案例:流数据解码详解
在大数据背景下,网络爬虫与FFmpeg结合,高效采集小红书短视频。需准备FFmpeg、Python及库如Requests和BeautifulSoup。通过设置User-Agent、Cookie及代理IP增强隐蔽性,解析HTML提取视频链接,利用FFmpeg下载并解码视频流。示例代码展示完整流程,强调代理IP对避免封禁的关键作用,助你掌握视频数据采集技巧。
275 7
FFmpeg 在爬虫中的应用案例:流数据解码详解
|
安全 关系型数据库 MySQL
Navicat工具设置MySQL权限的操作指南
通过上述步骤,您可以使用Navicat有效地为MySQL数据库设置和管理用户权限,确保数据库的安全性和高效管理。这个过程简化了数据库权限管理,使其既直观又易于操作。
1064 4
|
编解码 开发工具 Android开发
iOS平台如何实现毫秒级延迟的RTMP|RTSP播放器
在我的blog里面,最近很少有提到iOS平台RTMP推送|轻量级RTSP服务和RTMP|RTSP直播播放模块,实际上,我们在2016年就发布了iOS平台直播推拉流、转发模块,只是因为传统行业,对iOS的需求比较少,所以一直没单独说明,本文主要介绍下,如何在iOS平台播放RTMP或RTSP流。
245 6