位运算的奇技淫巧

常见位运算总结:

1、基础位运算

左移<<运算

将二进制数向左移位操作,高位溢出则丢弃,低位补0。

右移>>运算

右移位运算中,无符号数和有符号数的运算并不相同。对于无符号数,右移之后高位补0;对于有符号数,符号位一起移动,正数高位补0,负数高位补1

按位与&运算

有0就是0,巧计:&这个符号像是有两个0组合而成。

按位或 | 运算

有1就是1,巧计:|本身就像一个1

按位异或^运算(两种解释方法)

相同为0,相异为1,或者解释成无进位相加

2、给一个数n,确定它的二进制表示中的第x位是0还是1

(n >> x) & 1

&1后的结果就是0/1,因为1的二进制位除了最后一位,其他都是0,&0就是0

3、将一个数n的二进制位的第x位改成1

n =(1 << x)|  n

4、将一个数n的二进制位的第x位改成0

n = n & (~(1 << x))

5、位图的思想

本质上就是一个哈希表

6、提取一个数(n)二进制表示中最右侧的1(lowbit

n & -n

解释:-n的操作就是先取反,然后再+1,这样造成的影响是最右边的1前面都是n的相反数,这样再跟原先的n&,因为是相反数,所以有一方肯定是0,这样最右边的1前面的数字都变成了0,最右边1右边本身就是0。

7、干掉一个数(n)最右边的1

n &(n - 1)

8、位运算的优先级

为了避免记住闲杂的公式,我们只需要记住能加括号就加括号。

9、异或运算的运算规律

  • a ^ 0 = a
  • a ^ a = 0(消消乐)
  • a ^ b ^ c = a ^ (b ^ c)

上面的指示是位运算的基础知识,下面就带着上面的指示开始实操啦

第一题:
191. 位1的个数

编写一个函数,输入是一个无符号整数(以二进制串的形式),返回其二进制表达式中数字位数为 '1' 的个数(也被称为汉明重量)。

解析:

只需要每次右移&1判断是否为1。

原码:

class Solution {
public:int hammingWeight(uint32_t n) {int sum = 0;int ret = n;for(int i = 0;i<32;i++){if(ret & 1 == 1) sum++;ret = ret >> 1;}return sum;}
};

第二题、461. 汉明距离

两个整数之间的 汉明距离 指的是这两个数字对应二进制位不同的位置的数目。

给你两个整数 x 和 y,计算并返回它们之间的汉明距离。

解析:

根据题目来看,可能最先想到的就是异或操作,相同为 0,不同为 1。异或操作后结果为 0101,然后我们只需要统计出来二进制结果中 1 的个数就可以计算出来汉明距离啦。

原码:

class Solution {
public:int hammingDistance(int x, int y) {int ret = x ^ y;int sum = 0;//计算1的个数for(int i = 0;i<32;i++){if(ret & 1 == 1) sum++;ret = ret >> 1;} return sum;}
};

第三题、136. 只出现一次的数字

给你一个 非空 整数数组 nums ,除了某个元素只出现一次以外,其余每个元素均出现两次。找出那个只出现了一次的元素。

你必须设计并实现线性时间复杂度的算法来解决此问题,且该算法只使用常量额外空间。

解析:

这是一道很典型的运用^的题目,我们只需要理解异或运算符,这题就迎刃而解啦。

原码:

class Solution {
public:int singleNumber(vector<int>& nums) {int ret = 0;for(int i = 0;i<nums.size();i++){ret = ret ^ nums[i];}return ret;}
};

第四题、260. 只出现一次的数字 III

给你一个整数数组 nums,其中恰好有两个元素只出现一次,其余所有元素均出现两次。 找出只出现一次的那两个元素。你可以按 任意顺序 返回答案。

你必须设计并实现线性时间复杂度的算法且仅使用常量额外空间来解决此问题。

解析:

本题是上一题的升级版,

把nums中的元素全部异或起来的结果eor就是那两个只出现一次的数字的异或结果。而这两个数不相同,意味着eor至少有一位是1,我们可以用lowbit运算拿到最低位的1,然后遍历nums数组,将所有数nums[i]按照这一位是不是1分成两类,初始化num1=num2=0

  1. 如果当前位是1,就将nums[i]异或到num1​上。

  2. 如果当前位是0,就将nums[i]异或到num2​上。

这样一来,两个只出现一次的数就会被分别异或到num1​和num2​上,而其他数也会被分别异或到这两个数上。而由于其他数都出现了两次,所以最终它们就会被异或成0,num1​和num2​就是那两个只出现一次的数。

注意进行位运算的优先级,直接加上括号就好!!!

原码:

class Solution {
public:vector<int> singleNumber(vector<int>& nums) {int a = 0, b = 0;//记录两个不同的数int ret = 0;for(int i = 0;i<nums.size();i++)ret ^= nums[i];//进行lowbit运算,两者不同,二进制肯定有1int tmp = ret & (-(long long)ret);//防止数据溢出for(int i = 0;i<nums.size();i++){if((tmp & nums[i]) == 0)//注意优先级! a ^= nums[i];else b ^= nums[i];}return {a,b};}
};

第五题、面试题 01.01. 判定字符是否唯一

解析:

本题第一思想直接用哈希表解决,但题目中用说尽量不用数据结构,我们可以尝试用位图解决!

用位图解决,需要熟练掌握位运算技巧,对巩固位运算有很大帮助!

原码:

class Solution {
public:bool isUnique(string astr) {int bitmap = 0;//用位图思想解决int tmp = 0;int n = astr.size();//利用鸽巢原理优化if(n > 26) return false;for(int i = 0;i<astr.size();i++){tmp = astr[i] - 'a';//判断字符是否已经出现过if(((bitmap >> tmp) & 1) == 1) return false;//把当前字符加入位图中bitmap = bitmap | (1 << tmp);}return true;}
};

第六题、371. 两整数之和

给你两个整数 a 和 b ,不使用 运算符 + 和 - ,计算并返回两整数之和。

思路:

我们前面介绍了^运算的另一个功能是不进位相加,因此我们可以利用这个特性去解决这道题。

因为是不进位,所以我们要想办法去解决进位的问题,^运算是相同为0,相异为1,相异不可能进位,只有相同并且都是1的情况下,才会进位,因此我们直接&,查找出都是1,因为是进位,所以还要左移一位,(a & b)<< 1,然后分别重制a,b的值。

原码:

class Solution {
public:int getSum(int a, int b) {while(b){int tmp = a;a = a ^ b;b = ((tmp&b) << 1);}return a;}
};

第七题、137. 只出现一次的数字 II

给你一个整数数组 nums ,除某个元素仅出现 一次 外,其余每个元素都恰出现 三次 。请你找出并返回那个只出现了一次的元素。

你必须设计并实现线性时间复杂度的算法且使用常数级空间来解决此问题。

解析:

本题有点难度,两层嵌套循环,根据32位int,把每个数位相加再对3取的余数即可,将每个数想象成32位的二进制,对于每一位的二进制的1和0累加起来必然是3N或者3N+1, 为3N代表目标值在这一位没贡献,3N+1代表目标值在这一位有贡献(=1),然后将所有有贡献的位|起来就是结果。这样做的好处是如果题目改成K个一样,只需要把代码改成cnt%k,很通用~

原码:

class Solution {
public:int singleNumber(vector<int>& nums) {int ans = 0;int n = nums.size();for(int i = 0;i<32;i++)//依次去修改ans的每一位{int sum = 0;for(int j = 0;j<n;j++){//计算nums中所有数的第i位的和sum += (nums[j] >> i) & 1;}//把第i位修改if(sum % 3)   ans ^= (1 << i); }return ans;}
};

第八题、面试题 17.19. 消失的两个数字

给定一个数组,包含从 1 到 N 所有的整数,但其中缺了两个数字。你能在 O(N) 时间内只用 O(1) 的空间找到它们吗?

以任意顺序返回这两个数字均可。

解析:

本题是两道题的融合版。

  • 将所有的数异或在一起,记为tmp
  • 找到tmp中,比特位上为1的那一位
  • 根据不同的那一位,划分为两类异或

原码

class Solution {
public:vector<int> missingTwo(vector<int>& nums) {int a = 0,b = 0;int n = nums.size();int ret = 0;//先将所有数异或for(int i = 1;i<=n+2;i++)ret ^= i;for(int i = 0;i<n;i++)ret ^= nums[i];//lowbit运算找到最右边的1int tmp = ret & (-(long long)ret);//防止溢出for(int i = 0;i<n;i++){if((nums[i] & tmp) == 0) a ^= nums[i];else b ^= nums[i];}for(int i = 1;i<=n+2;i++){if((i & tmp) == 0) a ^= i;else b ^= i; }return {a,b};}
};

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/635941.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Python使用pyechart分析疫情确诊人数图(2024)

import json from pyecharts.charts import Map from pyecharts import options as opts# 首先打开文件获取数据 f open("/Desktop/python/Project/数据可视化/疫情.txt", "r", encoding"UTF-8") data f.read()# 字符串转化成json数据 data_js…

Java多线程--创建多线程的基本方式一:继承Thread类

文章目录 一、创建和启动线程&#xff08;1&#xff09;概述&#xff08;2&#xff09;方式1&#xff1a;继承Thread类1、使用步骤2、举例2.1 案例12.2 案例22.3 案例3 3、两个问题3.1 问题13.2 问题2 4、代码及总结 二、练习&#xff08;1&#xff09;方式一&#xff08;2&…

索引的概述和性能分析

索引index&#xff0c;是一种有序的数据结构&#xff0c;可以高效的获取数据&#xff0c;在数据库中维护着满足查找特定算法的数据结构&#xff0c;就是索引 无索引的情况&#xff0c;查询数据时会全表扫描&#xff0c;效率极低 索引结构 &#xff08;1&#xff09;二叉树&…

python解决求二叉树的最长同值路径问题

对于给定的一颗二叉树&#xff0c;需要找到最长的路径&#xff0c;并且该路径上的每个节点具有相同的值的问题&#xff0c;对于寻找到的这条路径可以经过根节点也可以不经过根节点&#xff0c;两个节点之间的路径长度是由他们的变数来表示的&#xff0c;给定如下图的二叉树 添加…

【 Qt 快速上手】-②- Qt 环境搭建

文章目录 1. Qt 开发工具概述1.1 Qt Creator 介绍1.2 Visual Studio 介绍1.3 Eclipse 介绍 2. Qt SDK 的下载与安装2.1 Qt SDK 的下载2.2 Qt SDK 的安装2.3 验证 Qt SDK 安装是否成功2.4 Qt 环境变量配置 1. Qt 开发工具概述 Qt 开发环境需要安装三个部分&#xff1a; C编译器…

小伙频繁发朋友圈引发分手,拼命“晒“生活是否成为一种病态行为?

根据《西湖之声》1月19日的报道&#xff0c;一个小伙子因为一天发十几条朋友圈而引起了他女友的不满&#xff0c;女友甚至提出了分手。现如今&#xff0c;朋友圈已经成为每个人自我形象展示的平台&#xff0c;认真发朋友圈不仅是表达自己的一种方式&#xff0c;也是一种自我释放…

redis缓存和本地缓存的应用设计

数据查询顺序 一级缓存&#xff1a;本地缓存 -》二级缓存&#xff1a;redis缓存 -》数据库 本地缓存和分布式缓存 本地缓存&#xff1a;基于jvm, 意思是程序放在哪&#xff0c;数据就存储在哪&#xff0c;不需要网络请求&#xff0c;特别快&#xff0c;但是需要占用jvm的内存…

Python利用Excel读取和存储测试数据完成接口自动化教程

http_request2.py用于发起http请求 #读取多条测试用例#1、导入requests模块import requests#从 class_12_19.do_excel1导入read_data函数from do_excel2 import read_datafrom do_excel2 import write_datafrom do_excel2 import count_case#定义http请求函数COOKIENonedef ht…

Spring Boot Aop 执行顺序

Spring Boot Aop 执行顺序 1. 概述 在 spring boot 项目中&#xff0c;使用 aop 增强&#xff0c;不仅可以很优雅地扩展功能&#xff0c;还可以让一写多用&#xff0c;避免写重复代码&#xff0c;例如&#xff1a;记录接口耗时&#xff0c;记录接口日志&#xff0c;接口权限&…

python 自动化模块 - pyautogui初探

python 自动化模块 - pyautogui 引言一、安装测试二、简单使用三、常用函数总结 引言 在画图软件中使用pyautogui拖动鼠标&#xff0c;画一个螺旋式的正方形 - (源码在下面) PyAutoGUI允许Python脚本控制鼠标和键盘&#xff0c;以自动化与其他应用程序的交互。API的设计非常简…

限流算法之流量控制的平滑之道:滑动时间窗算法

文章目录 引言简介优点缺点样例样例图样例代码 应用场景结论 引言 在互联网应用中&#xff0c;流量控制是一个重要的组件&#xff0c;用于防止系统过载和保护核心资源。常见的限流算法包括固定窗口算法和滑动时间窗算法。本文将重点介绍滑动时间窗算法&#xff0c;并分析其优缺…

基于Abaqus的三种钢筋混凝土梁数值模拟对比研究

混凝土结构抗压强度高&#xff0c;而抗拉强度大约只有其十分之一&#xff0c;在受到竖向荷载&#xff08;包括自重&#xff09;作用下&#xff0c;梁下部会产生拉应力&#xff0c;上部产生压应力&#xff0c;而由于其抗拉强度低&#xff0c;因此很小的荷载即可导致梁下部开裂&a…

Mysql中的日志系统

文章目录 1. 慢查询日志&#xff08;Slow Query Log&#xff09;1.1 是否开启慢查询日志1.2 开启慢查询日志&#xff0c;设置时间阈值1.2.1 修改文件my.ini1.2.2 重启mysql后配置生效 1.3 查看慢查询日志1.3.1 直接用文本编辑器打开1.3.2 使用mysqldumpslow进行分析 2. InnoDB …

C语言从入门到实战——文件操作

文件操作 前言一、 为什么使用文件二、 什么是文件2.1 程序文件2.2 数据文件2.3 文件名 三、 二进制文件和文本文件四、 文件的打开和关闭4.1 流和标准流4.1.1 流4.1.2 标准流 4.2 文件指针4.3 文件的打开和关闭4.4 文件的路径 五、 文件的顺序读写5.1 顺序读写函数介绍fgetcfp…

【音视频原理】图像相关概念 ③ ( RGB 色彩简介 | RGB 排列 | YUV 色彩简介 | YUV 编码好处 )

文章目录 一、RGB 色彩1、RGB 色彩简介2、RGB 排列 二、YUV 色彩1、YUV 色彩简介2、YUV 编码好处 一、RGB 色彩 1、RGB 色彩简介 RGB 是 计算机 中的 颜色编码方法 , 红 ( R ) / 绿 ( G ) / 蓝 ( B ) 三个颜色通道 可以设置不同的值 , 每个 通道 的 颜色值都可以取值 0 ~ 255 ,…

【已解决】namespace “Ui“没有成员 xxx

先说笔者遇到的问题&#xff0c;我创建一个QWidget ui文件&#xff0c;然后编辑的七七八八后&#xff0c;想要用.h与.cpp调用其&#xff0c;编译通过&#xff0c;结果报了这个错误&#xff0c;本方法不是普适性&#xff0c;但是确实解决了这个鸟问题。 问题来源 搭建ui后&…

数据分析师不加班的秘密,三行代码教你Python自动发送邮件

作为一名数据分析师&#xff0c;每天除了做数据日报&#xff0c;还要编写邮件正文和添加数据日报附件&#xff0c;发送给对应的负责人及销售个人&#xff0c;一般一封邮件应包含邮箱账户名、邮箱密码、发送人邮箱、邮件主题以及邮件正文。 本文借助Python工具&#xff0c;使用y…

MyBatis框架基础到进阶

1、为什么要学习MyBatis 如果没有MyBatis框架&#xff0c;我们依靠JDBC和连接池已经能够很好的和数据库进行交互了&#xff0c;而学习MyBatis框架最核心的原因是为了减少SQL语句对代码的侵入性。 因为在过往不管是使用连接池还是JDBC Templete&#xff0c;所有的SQL语句都写在代…

java.sql.SQLException: Failed to fetch schema of XXX 问题

遇到问题&#xff1a;java.sql.SQLException: Failed to fetch schema of pay_record表 i.s.r.d.s.s.c.AbstractTableMetaCache : get table meta of the table pay_record error: Failed to fetch schema of pay_record 原因分析&#xff1a; springcloud项目中使用了se…

上海亚商投顾:沪指冲高回落 旅游板块全天强势

上海亚商投顾前言&#xff1a;无惧大盘涨跌&#xff0c;解密龙虎榜资金&#xff0c;跟踪一线游资和机构资金动向&#xff0c;识别短期热点和强势个股。 一.市场情绪 沪指昨日冲高回落&#xff0c;创业板指跌近1%&#xff0c;北证50指数跌超3%。旅游、零售板块全天强势&#xf…