【优选算法】位运算 {位运算符及其优先级;位运算的应用:判断位,打开位,关闭位,转置位,位图,get lowbit,close lowbit;相关编程题解析}
一、位运算符及其优先级
我们知道,计算机中的数在内存中都是以二进制形式进行存储的 ,而位运算就是直接对整数在内存中的二进制位进行操作,因此其执行效率非常高,在程序中尽量使用位运算进行操作,这会大大提高程序的性能。
那么,涉及位运算的运算符如下表所示:

注意:参与位运算的对象只能是整型数据(int, unsigned, char),不能为实型
异或运算符的运算律
- 异或0:a^0 = a;
- 消消乐:a^a = 0;
- 交换律和结合律:abc = acb; abc = a(bc);
位运算符的优先级
优先级需要弄清楚,如果不太清楚可以加小括号确保是想要的运算顺序,这里只是相对优先级,即只是和一些常用的算术运算符做比较。

二、位运算的应用
2.1 判断位
给一个数n,确定它的二进制表示中的第x位是0还是1
算法:(n>>x)&1
原理:按位与的运算规则——有0则0,遇1不变
举例:判断第3位
- 11001010 //n
00011001 //n>>3
00000001 //&1
00000001 //结果
2.2 打开位
将一个数n二进制表示的第x位修改成1
算法:n |= (1<<x)
原理:按位或的运算规则——有1则1,遇0不变
举例:打开第4位
- 11001010 //目标
00010000 //1<<4
11011010 //|= 得结果
2.3 关闭位
将一个数n二进制表示的第x位修改成0
算法:n &= ~(1<<x)
原理:按位与的运算规则——有0则0,遇1不变
举例:关闭第7位
- 11001000 //目标
10000000 //1<<7
01111111 //~(1<<7)
01001000 //&= 得结果
2.4 转置位
将一个数n二进制表示的第x位转置(0变1,1变0)
算法:n ^= (1<<x)
原理:按位异或的运算规则——0变1,1变0
举例:转置第4位
- 11011010 //目标
00010000 //1<<4
11001010 //^= 得结果
2.5 位图

定义和特性:位图是一种数据结构,它由一个二进制位数组或者比特数组组成,每个位(bit)只能存储 0 或 1。位图通常被用来表示大量整数的集合,通过位的状态来表示该整数是否出现在集合中。位图支持高效的位操作(如按位与、按位或、按位异或等),适合用于高效地存储和操作大量的布尔型数据。
实现方式:位图可以被实现为一个数组,其中每个元素都是一个字节,而每个字节又包含8个位。对于很大的位图,可以使用多个数组进行分段存储。位图通常不仅仅用于表示整数的集合,还可以用于标记某个特定值是否存在。
详细内容请阅读文章:【高阶数据结构】哈希的其他应用 {位图的介绍及实现,位图的组合应用;布隆过滤器的介绍及实现,布隆过滤器的应用;哈希切分}-CSDN博客
2.6 get lowbit
提取一个数n二进制表示中最低位的1
算法:n & -n
原理:-n(按位取反再加1)将最低位的1左边的位(不包括logbit位)全部转置,左边转置后按位与得0,右边相同位按位与不变。
举例:
- 11011000 //目标
00101000 //-n
00001000 //& 得结果
2.7 close lowbit
关闭一个数n二进制表示中最低位的1
算法:n & (n-1)
原理:n-1 将最低位的1右边的位(包括logbit位)全部转置,左边相同位按位与不变,右边转置后按位与得0。
举例:
- 11011000 //目标
11010111 //n-1
11010000 //& 得结果
2.8 其他
-
位运算实现乘除法:将a左移一位实现*2,将a右移一位实现/2。
- a < < n ≡ a ∗ 2^n
- a > > n ≡ a / 2^n
-
统计二进制数中有多少个1:
int func(int x){int count=0;while (x){count++;x=x&(x-1); //将lowbit关闭}return count; } -
字符的大小写转换:对应大小写字母ASSIC码的二进制数只有第5位不同(大写为0,小写为1),因此可以通过操作第5位实现大小的相互转换
- 字符小写转大写:ch&=~32;
-
字符大写转小写:ch|=32;
-
字符大小写互换:ch^=32;
-
交换两变量的值:a=a^b; b=a^b; a=a^b;(异或运算符的运算律:结合律、消消乐)
三、相关编程题
3.1 位1的个数
题目链接
191. 位1的个数 - 力扣(LeetCode)
题目描述

算法原理
不断的close lowbit,每关闭一个1count就++,直到将所有的1都关闭,量的值变为0。
编写代码
class Solution {
public:int hammingWeight(int n) {int count = 0;while(n>0){n &= (n-1);++count;}return count;}
};
3.2 比特位计数
题目链接
338. 比特位计数 - 力扣(LeetCode)
题目描述

算法原理
同上 close lowbit
编写代码
class Solution {
public:vector<int> countBits(int n) {vector<int> ans(n+1, 0);for(int i = 0; i <= n; ++i){int count = 0;int k = i;while(k>0){++count;k &= k-1;}ans[i] = count;}return ans;}
};
3.3 汉明距离
题目链接
461. 汉明距离 - 力扣(LeetCode)
题目描述

算法原理
异或运算:相异为1,相同为0。tmp = x^y将x和y二进制表示中不同的位置置为1,相同的位置置为0。再统计tmp中位1的个数即可,原理同上 close lowbit
编写代码
class Solution {
public:int hammingDistance(int x, int y) {int tmp = x ^ y;int count = 0;while(tmp>0){++count;tmp &= tmp-1;}return count;}
};
3.4 只出现一次的数字
题目链接
136. 只出现一次的数字 - 力扣(LeetCode)
题目描述

算法原理
异或运算的运算律:消消乐
编写代码
class Solution {
public:int singleNumber(vector<int>& nums) {int ret = 0;for(auto e : nums){ret ^= e;}return ret;}
};
3.5 只出现一次的数Ⅲ
题目链接
260. 只出现一次的数字 III - 力扣(LeetCode)
题目描述

算法原理
- 将所有的数按位异或到tmp,最终其实就是只出现一次的两个数的异或结果,即将两个数不同的位置置为1。
- get lowbit将tmp的最低位1取出(还是存入tmp)。注意有符号数需要特殊处理INT_MIN(符号位为1,其他位为0),有符号数取反的位操作是:符号位不变,其他位取反再+1。INT_MIN取反会溢出。实际上INT_MIN的lowbit就是它本身。
- 再次遍历数组,判断所有数的tmp位(异或结果的最低位1),将只出现一次的两个数分到不同的组中进行异或,最终就能分别得到这两个数了。
编写代码
class Solution {
public:vector<int> singleNumber(vector<int>& nums) {int tmp = 0;for(auto e : nums){tmp ^= e;}tmp = tmp==INT_MIN? tmp:tmp&(-tmp); //get lowbitvector<int> ret(2, 0);for(auto e : nums){if(e & tmp){ret[0] ^= e;}else{ret[1] ^= e;}}return ret;}
};
3.6 判定字符是否唯一
题目链接
面试题 01.01. 判定字符是否唯一 - 力扣(LeetCode)
题目描述

算法原理

编写代码
//用一个int数据充当位图
class Solution {
public:bool isUnique(string astr) {// 利用鸽巢原理进行优化if(astr.size() > 26)return false;// 用位图判断一个字符是否在集合中int bitmap = 0;for(auto e : astr){int tmp = 1 << (e-'a');if(!(bitmap & tmp)){bitmap |= tmp;}else{return false;}}return true;}
};//用STL的bitset数据结构
class Solution {
public:bool isUnique(string astr) {if(astr.size() > 26)return false;bitset<26> bs;for(auto e : astr){int x = e - 'a'; //位图的第x位if(!bs.test(x)){bs.set(x);}else{return false;}}return true;}
};
3.7 丢失的数字
题目链接
268. 丢失的数字 - 力扣(LeetCode)
题目描述

算法原理

编写代码
class Solution {
public:int missingNumber(vector<int>& nums) {int ret = 0;int i = 0;for(; i < nums.size(); ++i){ret ^= nums[i];ret ^= i;}ret ^= i;return ret;}
};
3.8 两整数之和
题目链接
371. 两整数之和 - 力扣(LeetCode)
题目描述

算法原理

编写代码
class Solution {
public:int getSum(int a, int b) {int bitsum = a ^ b; //无进位相加的结果int bitcarry = (a & b)<<1; //进位的结果while(bitcarry != 0) //当不再有进位时退出循环{a = bitsum;b = bitcarry;bitsum = a ^ b;bitcarry = (a & b)<<1;}return bitsum;}
};
3.9 只出现一次的数字Ⅱ
题目链接
137. 只出现一次的数字 II - 力扣(LeetCode)
题目描述

算法原理
依次确定每一个二进制位
为了方便叙述,我们称「只出现了一次的元素」为「答案」。
由于数组中的元素都在 int(即 32 位整数)范围内,因此我们可以依次计算答案的每一个二进制位是 0 还是 1。
具体地,考虑答案的第 i 个二进制位(i 从 0 开始编号),它可能为 0 或 1。对于数组中非答案的元素,每一个元素都出现了 3 次,对应着第 i 个二进制位的 3 个 0 或 3 个 1,无论是哪一种情况,它们的和都是 3 的倍数(即和为 0 或 3)。因此:
答案的第 i 个二进制位就是数组中所有元素的第 i 个二进制位之和除以 3 的余数。
这样一来,对于数组中的每一个元素 x,我们使用位运算 (x >> i) & 1得到 x 的第 i 个二进制位,并将它们相加再对 3 取余,得到的结果一定为 0 或 1,即为答案的第 i 个二进制位。
编写代码
class Solution {
public:int singleNumber(vector<int>& nums) {int ret = 0;for(size_t i = 0; i < 32; ++i){int bitsum = 0;for(auto e : nums){bitsum+=(e>>i)&1;}bitsum %= 3;ret |= (bitsum<<i);}return ret;}
};
3.10 消失的两个数字
题目链接
面试题 17.19. 消失的两个数字 - 力扣(LeetCode)
题目描述

算法原理

编写代码
class Solution {
public:vector<int> missingTwo(vector<int>& nums) {int tmp = 0;//异或到一起for(auto e : nums) tmp ^= e; //原数组for(int i = 1; i<=nums.size()+2; ++i) tmp ^= i; //全数组//此时的tmp种存放的是消失的两个数字的异或结果int lowbit = tmp==INT_MIN? tmp:tmp&(-tmp);vector<int> ret(2, 0);//划分成两类异或for(auto e : nums) //原数组if(e & lowbit) ret[0] ^= e;else ret[1] ^= e;for(int i = 1; i<=nums.size()+2; ++i) //全数组if(i & lowbit) ret[0] ^= i;else ret[1] ^= i; return ret;}
};
相关文章:
【优选算法】位运算 {位运算符及其优先级;位运算的应用:判断位,打开位,关闭位,转置位,位图,get lowbit,close lowbit;相关编程题解析}
一、位运算符及其优先级 我们知道,计算机中的数在内存中都是以二进制形式进行存储的 ,而位运算就是直接对整数在内存中的二进制位进行操作,因此其执行效率非常高,在程序中尽量使用位运算进行操作,这会大大提高程序的性…...
服务器数据恢复—服务器正常断电重启后raid信息丢失的数据恢复案例
服务器数据恢复环境: 一台某品牌DL380 G4服务器,服务器通过该服务器品牌smart array控制器挂载了一台国产的磁盘阵列,磁盘阵列中有一组由14块SCSI硬盘组建的RAID5。服务器安装LINUX操作系统,搭建了NFSFTP,作为内部文件…...
如何理解kmp的套娃式算法啊?
概念 KMP算法,全称Knuth Morris Pratt算法 。文章大部分内容出自《数据结构与算法之美》 核心思想 假设主串是a,模式串是b 在模式串与主串匹配的过程中,当遇到不可匹配的字符的时候,对已经对比过的字符,是否能找到…...
python中树的运用样例
目录 一、文件系统样例 二、Trie树 一、文件系统样例 class FileNode:def __init__(self, name, is_fileFalse):self.name nameself.is_file is_fileself.children []def add_child(self, child):self.children.append(child)# 创建文件系统结构 root FileNode("roo…...
C++学习/复习5--构造函数与初始化/static成员/友元/内部类/匿名对象/编译器的拷贝构造优化
一、本章概要 二、再谈构造函数 1.构造体赋初值与初始化 2.初始化列表与初始化 2.1定义 2.2注意事项与举例 3.explicit关键字与构造函数 3.1隐式类型转换 也叫做自动类型转换 这种转换通常是从存储范围小的类型到存储范围大的类型,或者是从低精度的数值类型到高…...
数学建模--LaTeX基本介绍和入门
1.引言 (1)上次我们介绍到了我们这个团队第一次参加这个数学建模比赛,就是这个电工杯,我是一名论文手,我们在这个下午也是对于这个比赛过程中出现的问题做了相应的分析,每个人也是进行了反思,知…...
【Java面试】二、Redis篇(中)
文章目录 1、Redis持久化1.1 RDB1.2 AOF1.3 RDB与AOF的对比 2、数据过期策略(删除策略)2.1 惰性删除2.2 定期删除 3、数据淘汰策略4、主从复制4.1 主从全量同步4.2 增量同步 5、哨兵模式5.1 服务状态监控5.2 哨兵选主规则5.3 哨兵模式下,Redi…...
二进制安装Kubernetes(k8s)v1.30.1
二进制安装Kubernetes(k8s)v1.30.1 https://github.com/cby-chen/Kubernetes 开源不易,帮忙点个star,谢谢了 介绍 kubernetes(k8s)二进制高可用安装部署,支持IPv4IPv6双栈。 我使用IPV6的目的是…...
俄罗斯半导体领域迈出坚实步伐:首台光刻机诞生,目标直指7纳米工艺
近日,国外媒体纷纷报道,俄罗斯在半导体技术领域取得了重要突破,首台光刻机已经制造完成并正在进行严格的测试阶段。这一里程碑式的事件标志着俄罗斯在自主发展半导体技术的道路上迈出了坚实的一步。 据俄罗斯联邦工业和贸易部副部长瓦西里-什…...
什么是容器:从基础到进阶的全面介绍
✨✨ 欢迎大家来访Srlua的博文(づ ̄3 ̄)づ╭❤~✨✨ 🌟🌟 欢迎各位亲爱的读者,感谢你们抽出宝贵的时间来阅读我的文章。 我是Srlua小谢,在这里我会分享我的知识和经验。&am…...
力扣 第 399 场周赛 解题报告 | 珂学家 | 调和级数 + 分块DP
前言 T1. 优质数对的总数 I 题型: 签到 class Solution:def numberOfPairs(self, nums1: List[int], nums2: List[int], k: int) -> int:res 0for v1 in nums1:for v2 in nums2:if v1 % (v2 * k) 0:res 1return resT2. 压缩字符串 III 思路: 模拟 感觉引入一个栈&…...
Redis的下载、安装、启动和初尝试【超级简单】
redis最好是在Linux系统中使用,这是最接近生产实际的环境。 不过,我们初学者,目的是学习Redis的使用、原理,如果在Linux下直接学习Redis,很可能会因为命令不熟悉而劝退,这是不好的。 因此,我主张…...
v-cloak 用于在 Vue 实例渲染完成之前隐藏绑定的元素
如果你是后端开发者(php),在接触一些vue2开发的后台时,会发现有这段代码: # CDN <script src"https://cdn.jsdelivr.net/npm/vue2/dist/vue.js"></script> # 或 <script src"https://cd…...
港股:并不意外的获利了结
中金公司表示,风险偏好驱动的反弹已经较为充分,分歧和获利了结也不意外。接下来或在当前水平震荡盘整,等待更多催化剂。 在持续一个月的大涨后,港股市场上周出现明显回调。此前我们多次提示,市场已经超买,情…...
Python项目开发实战:工厂库存管理系统(案例教程)
一、项目背景与意义 随着制造业的快速发展,工厂库存管理成为了企业运营中不可或缺的一部分。一个高效的库存管理系统能够确保物料供应的及时性、降低库存成本、提高生产效率。因此,我们决定使用Python开发一个工厂库存管理系统,以满足工厂日常库存管理的需求。 二、系统需求…...
VS2022 嘿嘿
还是大二的时候就开始用这个,但居然是为了用PB,-_-|| 用了段时间换成了C#,依稀还记得大佬们纠正我的读法,别读C井,应该读C夏普。。。 安装过程其实也没啥,就是关键Key得花时间找,我好不容易搞…...
Flutter 中的 PhysicalShape 小部件:全面指南
Flutter 中的 PhysicalShape 小部件:全面指南 在Flutter中,PhysicalShape小部件是一个能够为子组件添加物理效果的边框和阴影的装饰性小部件。它能够模拟真实世界中物体的立体感,通过在子组件的周围创建一个可自定义的形状,并添加…...
CAD二次开发(6)-用户交互之选择集
1. 简单测试 测试让选中的图形描红 [CommandMethod("SeleDemo")]public void SeleDemo(){Database db HostApplicationServices.WorkingDatabase;Editor ed Application.DocumentManager.MdiActiveDocument.Editor;PromptSelectionResult psr ed.GetSelection();…...
如何使用性能监控工具分析JVM性能瓶颈
1、jConsole: jConsole是JDK自带的Java监控和管理控制台。它提供了一个图形用户界面(GUI),用于监控和管理Java应用程序的性能和资源消耗。 使用方法:打开jdk\bin\jconsole.exe,连接到正在运行的Java进程&a…...
解决vite打包只生成了一个css和js文件问题
文章目录 1. 打包遇到的问题2. 问题原因及修改3. 调整后再次打包🆗 1. 打包遇到的问题 今天整了一个项目,试了下打包,发下打包后只生成了一个css文件,和一个js文件, 这样肯定是不行的,因为这样这个文件的包…...
IGP(Interior Gateway Protocol,内部网关协议)
IGP(Interior Gateway Protocol,内部网关协议) 是一种用于在一个自治系统(AS)内部传递路由信息的路由协议,主要用于在一个组织或机构的内部网络中决定数据包的最佳路径。与用于自治系统之间通信的 EGP&…...
前端导出带有合并单元格的列表
// 导出async function exportExcel(fileName "共识调整.xlsx") {// 所有数据const exportData await getAllMainData();// 表头内容let fitstTitleList [];const secondTitleList [];allColumns.value.forEach(column > {if (!column.children) {fitstTitleL…...
全球首个30米分辨率湿地数据集(2000—2022)
数据简介 今天我们分享的数据是全球30米分辨率湿地数据集,包含8种湿地亚类,该数据以0.5X0.5的瓦片存储,我们整理了所有属于中国的瓦片名称与其对应省份,方便大家研究使用。 该数据集作为全球首个30米分辨率、覆盖2000–2022年时间…...
令牌桶 滑动窗口->限流 分布式信号量->限并发的原理 lua脚本分析介绍
文章目录 前言限流限制并发的实际理解限流令牌桶代码实现结果分析令牌桶lua的模拟实现原理总结: 滑动窗口代码实现结果分析lua脚本原理解析 限并发分布式信号量代码实现结果分析lua脚本实现原理 双注解去实现限流 并发结果分析: 实际业务去理解体会统一注…...
Axios请求超时重发机制
Axios 超时重新请求实现方案 在 Axios 中实现超时重新请求可以通过以下几种方式: 1. 使用拦截器实现自动重试 import axios from axios;// 创建axios实例 const instance axios.create();// 设置超时时间 instance.defaults.timeout 5000;// 最大重试次数 cons…...
深入解析C++中的extern关键字:跨文件共享变量与函数的终极指南
🚀 C extern 关键字深度解析:跨文件编程的终极指南 📅 更新时间:2025年6月5日 🏷️ 标签:C | extern关键字 | 多文件编程 | 链接与声明 | 现代C 文章目录 前言🔥一、extern 是什么?&…...
使用Spring AI和MCP协议构建图片搜索服务
目录 使用Spring AI和MCP协议构建图片搜索服务 引言 技术栈概览 项目架构设计 架构图 服务端开发 1. 创建Spring Boot项目 2. 实现图片搜索工具 3. 配置传输模式 Stdio模式(本地调用) SSE模式(远程调用) 4. 注册工具提…...
现有的 Redis 分布式锁库(如 Redisson)提供了哪些便利?
现有的 Redis 分布式锁库(如 Redisson)相比于开发者自己基于 Redis 命令(如 SETNX, EXPIRE, DEL)手动实现分布式锁,提供了巨大的便利性和健壮性。主要体现在以下几个方面: 原子性保证 (Atomicity)ÿ…...
Selenium常用函数介绍
目录 一,元素定位 1.1 cssSeector 1.2 xpath 二,操作测试对象 三,窗口 3.1 案例 3.2 窗口切换 3.3 窗口大小 3.4 屏幕截图 3.5 关闭窗口 四,弹窗 五,等待 六,导航 七,文件上传 …...
根目录0xa0属性对应的Ntfs!_SCB中的FileObject是什么时候被建立的----NTFS源代码分析--重要
根目录0xa0属性对应的Ntfs!_SCB中的FileObject是什么时候被建立的 第一部分: 0: kd> g Breakpoint 9 hit Ntfs!ReadIndexBuffer: f7173886 55 push ebp 0: kd> kc # 00 Ntfs!ReadIndexBuffer 01 Ntfs!FindFirstIndexEntry 02 Ntfs!NtfsUpda…...
