【数据结构与算法】巧用位运算

news2024/9/28 0:58:40

【数据结构与算法】巧用位运算

文章目录

  • 【数据结构与算法】巧用位运算
    • 位运算的巧思
      • 用位运算来求集合公式
      • 用位移求集合公式
      • 二进制库函数
    • 位扩展:基础例题
    • 例题LC190——用到左移和或运算
    • 异或
      • 运算法则
      • 经典例题:[LC136 唯一数](https://leetcode.cn/problems/single-number/description/)

位运算的巧思

总结来源:分享|从集合论到位运算,常见位运算技巧分类总结!

用位运算来求集合公式

术语:

  • 与:& 11为1 ,其余为0
  • 或:| 有1为1, 00为0
  • 异或:⊕(^) 相异为1, 相同为0
  • 反:~ 按位取反
术语集合位运算集合示例位运算示例
交集A∩Ba&b{0,2,3}
∩{0,1,2}
={0,2}
1101
&0111
= 0101
并集A∪Ba|b{0,2,3}
∪{0,1,2}
={0,2}
1101
| 0111
= 1111
对称差
A,B相交以外的元素
AΔBa^b{0,2,3}
Δ{0,1,2}
={1,3}
1101
^0111
=1010
差(B不为子集)A\Ba&(~b){0,2,3}
\{1,2}
={0,3}
1101
&1001
=1001
差(B为子集)A\B B⊆Aa^b{0,2,3}
\{0,2}
={3}
1101
^0101
=1000
包含于A⊆Ba&b == a
or(用于判断)
a|b == b
{0, 2} ⊆{0,2,3}0101&1101==0101
OR
0101 | 1101 == 0101

用位移求集合公式

术语:

  • 左移<<:低位补零,相当于乘以 2 i 2^i 2i
  • 右移>>: 高位补零,相当于除以 2 i 2^i 2i

补充说明,在使用集合和位运算的过程中,我们需要明确,它们是如何一一对应的。

假设我们有一个不包含相同元素的数组,大小为32。

  1. 如果全部元素都已经选中,则其表示的集合当为全集——(1 << 32) -1

因为这样我们会得到32个1,1代表该index的元素已被选中。

  1. 现在我们根据某规则从其中已经挑选一些元素,现在仍需继续挑选一些元素,假设已挑选的集合为s

    我们判断index 为 i的元素是否被选中,可以使用(s >> i) & 1 == 1进行判断,其原理是把i位的元素右移到末尾,相与计算是否被选中。

其余计算巧思见下图

术语集合位运算集合示例位运算示例
空集0
单元素集合{i}1 << i{2}1 << 2
全集U={0,1,2,⋯n−1}(1 << n)−1{0,1,2,3}(1 << 4)−1
补集∁u𝑆=𝑈∖𝑆((1 << n)−1)⊕sU={0,1,2,3}
S = {1,2}
S相对于U的补集
是U中所有不属于S中的元素
这里的U为全集,故S包含于U
1111
^ 0110
=1001
属于i ∈ S(s>>i)&1 == 12 ∈ {0,2,3}(1101 >> 2)& 1 ==1
不属于i∈/S(s >> i) & 1 ==01∈/{0,2,3}(1101 >> 1) & 1== 0
添加元素S U {i}s | (1 << i){0,3}∪{2}1001 ∣ (1 << 2)
删除元素S∖{i}s&∼(1 << i){0,2,3}∖{2}1101&∼(1 << 2)
删除元素
(删除的是子集)
S∖{i}, iSs⊕(1 << i){0,2,3}∖{2}1101
^(1 << 2)
删除最小元素
(删除最低位元素)
s & (s - 1)备注:如果s为2的幂次方,
那么结果为0
s = 101100
s-1 = 101011
s&(s-1) = 101000
包含最小元素的子集(lowbit)即二进制最低1
及之后的0
s & (-s)(-s)这是补码,不是位反,
及最低1左侧取反,右侧不变
s = 101100
~s = 010011
-s = (~s)+1 = 010100
s & -s = 000100

二进制库函数

注意,当s = 0时,对以下API可能属于未定义行为

对C++ 的 long long,需使用__builtin_popcountll,即函数名后添加ll(小写L)

术语C++说明
集合大小__builtin_popcount(s)计算s的二进制表达中1的个数
二进制长度32-__builtin_clz(s)__builtin_clz()返回从最高位开始的前导0的个数
集合最大元素31-__builtin_clz(s)
集合最小元素31-__builtin_clz(s)

位扩展:基础例题

  • LeetCode 78 组合:
    不含重复值的整数数组的所有子集
  • 核心代码:
def subsets(self, nums):
    '''
    位扩展写法:把新的元素依次加到前面的结果集里
            组成新的集合再加入结果集
    注意:不要超过本轮的结果集
    '''
    res = [[]]
    for value in nums:
        long = len(res)
        for pos in range(long):
            temp = copy.deepcopy(res[pos])
            temp.append(value)
            res.append(temp)
    return res

例题LC190——用到左移和或运算

示例代码1:

uint32_t reverseBits(uint32_t n)
    {
        uint32_t rev = 0;
        for (int i = 0; i < 32 && n > 0; ++i)
        {
            // n&1使用的是n的末尾与1相与,末位为1则为1
            // |= 有1为1,全0为0
            // 这里相当于,不断把n的低位数传到rev未定义的高位
            rev |= (n & 1) << (31 - i);
            /*
            如:
            n = 00000010100101000001111010011100
            i = 0
            n&1 = 0
            31-i = 31
            (n&1)<<(31-i)得到的是
            0(这是当前匹配的结果0)【因为是左移,后面补31个0】
            形象点就是把n的末尾直接传送到了rev的最高位。
            也就是这个循环的意义。
            */
            // 去掉已经传递的末尾
            n >>= 1;
        }
        return rev;
    }

异或

基本概念:如果a、b两个值不相同,则异或结果为1。如果a、b两个值相同,异或结果为0。

运算法则

在这里插入图片描述

在C++中用^符号表示异或,可以用异或交换两个数

void swap(int &a, int &b){
    a = a^b;
    b = b^a;	//b = b^a^b  = a
    a = a^b;	// a = a^b^a = b
}

经典例题:LC136 唯一数

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

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

相关文章

stm32单片机个人学习笔记3(GPIO输出)

前言 本篇文章属于stm32单片机&#xff08;以下简称单片机&#xff09;的学习笔记&#xff0c;来源于B站教学视频。下面是这位up主的视频链接。本文为个人学习笔记&#xff0c;只能做参考&#xff0c;细节方面建议观看视频&#xff0c;肯定受益匪浅。 STM32入门教程-2023版 细…

基于千问大模型Intel G8i开发主动问询导购助手

文章目录 1. 背景2.环境介绍2.1 硬件环境2.2 软件环境 3. 大模型环境部署3.1 准备硬件资源 3.2 大模型部署3.1 部署Docker3.2 部署Intel xFasterTransformer容器3.3 准备模型数据3.4 运行模型进行AI对话 4. 构建主动问询导购助手应用 1. 背景 北京又开始发放消费券啦&#xff…

整个场面要hold住-《分析模式》漫谈32

DDD领域驱动设计批评文集 做强化自测题获得“软件方法建模师”称号 《软件方法》各章合集 “Analysis Patterns”的第一章有这么一句&#xff1a; It is important to be clear to them that I am not holding them up as gospel, and if they are not comfortable, I will …

RedisTemplate操作ZSet的API

文章目录 ⛄概述⛄常见命令有⛄RedisTemplate API❄️❄️ 向集合中插入元素&#xff0c;并设置分数❄️❄️向集合中插入多个元素,并设置分数❄️❄️按照排名先后(从小到大)打印指定区间内的元素, -1为打印全部❄️❄️获得指定元素的分数❄️❄️返回集合内的成员个数❄️❄…

鸿蒙应用开发:音频播放

鸿蒙系统提供了多样化的API,来帮助开发者完成音频播放的开发,不同的API适用于不同音频数据格式、音频资源来源、音频使用场景,甚至是不同开发语言。因此,选择合适的音频播放API,有助于降低开发工作量,实现更佳的音频播放效果。 本节介绍通过Media Kit实现音频播放。 AVP…

【机器学习】--- 深度学习中的注意力机制

深度学习中的注意力机制 在深度学习领域&#xff0c;注意力机制&#xff08;Attention Mechanism&#xff09;已经成为近年来最受瞩目的研究热点之一。它不仅提升了现有模型的性能&#xff0c;更启发了全新的网络结构&#xff0c;如Transformer模型。注意力机制被广泛应用于自…

SMA2:代码实现详解——Image Encoder篇(Hiera章)

SMA2:代码实现详解——Image Encoder篇&#xff08;Hiera&#xff09; 写在前面 大家在SMA2:代码实现详解——Image Encoder篇&#xff08;FpnNeck&#xff09;下的留言我已收到&#xff0c;感谢大家的支持&#xff0c;后面如果遇到比较难以讲清的部分可能会使用视频的形式。…

jsp+sevlet+mysql图书管理系统

jspsevletmysql图书管理系统 一、系统介绍二、功能展示1.图书查询(学生)2.借阅信息(学生)3.借阅历史(学生)4.借阅历史(管理员)5.读者管理(管理员)6.图书分类(管理员)7.图书借阅信息(管理员)8.图书归还信息(管理员) 四、其它1.其他系统实现 一、系统介绍 系统主要功能&#xff…

《Linux运维总结:基于ARM64+X86_64架构CPU使用docker-compose一键离线部署mongodb 7.0.14容器版副本集群》

总结&#xff1a;整理不易&#xff0c;如果对你有帮助&#xff0c;可否点赞关注一下&#xff1f; 更多详细内容请参考&#xff1a;《Linux运维篇&#xff1a;Linux系统运维指南》 一、部署背景 由于业务系统的特殊性&#xff0c;我们需要面向不通的客户安装我们的业务系统&…

机器学习和深度学习的常见概念总结(多原创图)

目录 使用说明一、未分类损失函数&#xff08;Loss Function&#xff09;1. **损失函数的作用**2. **常见的损失函数**2.1. **均方误差&#xff08;MSE, Mean Squared Error&#xff09;**2.2. **均方根误差&#xff08;RMSE, Root Mean Squared Error&#xff09;**2.3. **平均…

【云原生安全篇】一文掌握Harbor集成Trivy应用实践

【云原生安全篇】一文掌握Harbor集成Trivy应用实践 目录 1 概念 1.1 什么是 Harbor 和 Trivy&#xff1f; 1.1.1 Harbor 1.1.2 Trivy 1.2 Harbor 与 Trivy 的关系 Trivy 在 Harbor 中的作用&#xff1a; 1.3 镜像扫描工作流程 2 实战案例&#xff1a;在Harbor 配置 Trivy …

SafaRi:弱监督引用表达式分割的自适应序列转换器

引用表达式分割(reference Expression Segmentation, RES)旨在提供文本所引用的图像(即引用表达式)中目标对象的分割掩码。 目前存在的挑战 1)现有的方法需要大规模的掩码注释。 2)此外&#xff0c;这种方法不能很好地推广到未见/零射击场景 改进 1&#xff09;提出了一个弱…

探索自动化的魔法:Python中的pyautogui库

文章目录 探索自动化的魔法&#xff1a;Python中的 pyautogui 库背景&#xff1a;为什么选择pyautogui&#xff1f;pyautogui是什么&#xff1f;如何安装pyautogui&#xff1f;五个简单的库函数使用方法场景应用常见Bug及解决方案总结 探索自动化的魔法&#xff1a;Python中的 …

VirtualBox桥接网卡消失,安装Docker后导致桥接网卡服务消失问题解决记录

问题记录&#xff1a;VirtualBox虚拟机的桥接网卡消失 记录时间&#xff1a;2024.9.14 系统&#xff1a;win10 问题已解决。 原因&#xff1a; 猜测是由于安装Docker&#xff0c;也会使用我们的网卡进行虚拟化&#xff0c;导致网卡与virtualbox的桥接服务丢失。 解决方案…

基于python+django+vue的鲜花商城系统

作者&#xff1a;计算机学姐 开发技术&#xff1a;SpringBoot、SSM、Vue、MySQL、JSP、ElementUI、Python、小程序等&#xff0c;“文末源码”。 专栏推荐&#xff1a;前后端分离项目源码、SpringBoot项目源码、SSM项目源码 系统展示 【2025最新】基于pythondjangovueMySQL的线…

三维点云处理(C++)学习记录——PDAL

一、OSGeo4W简概 OSGeo4W是一个基于Windows系统&#xff08;版本7-11&#xff09;的开源地理软件二进制包发布平台。OSGeo4W包括开源GIS桌面应用程序&#xff08;QGIS、GRASS GIS&#xff09;、地理空间库&#xff08;PROJ、GDAL/OGR、GEOS、SpatiaLite、SAGA GIS&#xff09;、…

org.flowable.bpmn.exceptions.XMLException: 元素类型 必须由匹配的结束标记

flowable在流程部署时经常汇报这个错误&#xff1a; org.flowable.bpmn.exceptions.XMLException: 元素类型... 必须由匹配的结束标记 经检查发现是数据库存的中午乱码导致xml结构异常了 解决办法如下&#xff1a; 在catalina.bat文件中找到如下地方&#xff0c;加入 -Dfile.…

Python爬取某猫投诉数据(含signature参数分析与算法还原)

文章目录 1. 写在前面2. 接口分析3. 爬虫实现 【&#x1f3e0;作者主页】&#xff1a;吴秋霖 【&#x1f4bc;作者介绍】&#xff1a;擅长爬虫与JS加密逆向分析&#xff01;Python领域优质创作者、CSDN博客专家、阿里云博客专家、华为云享专家。一路走来长期坚守并致力于Python…

电商数据采集分析全流程分享||电商数据API接口

电商数据监测&#xff0c;能为品牌发展提供参考依据&#xff0c;已经成为了业内共识。依托智能系统&#xff0c;将电商数据转换为有价值的营销情报&#xff0c;只需三步&#xff1a; 数据采集 可采集30多个电商平台数据&#xff0c;采集字段高达40多个&#xff0c;包含标题、价…

网络穿透:TCP 打洞、UDP 打洞与 UPnP

在现代网络中&#xff0c;很多设备都处于 NAT&#xff08;网络地址转换&#xff09;或防火墙后面&#xff0c;这使得直接访问这些设备变得困难。在这种情况下&#xff0c;网络穿透技术就显得非常重要。本文将介绍三种常用的网络穿透技术&#xff1a;TCP 打洞、UDP 打洞和 UPnP。…