目录

1.位图的引入

2.位图概念

3.位图的实现

3.1前提准备

3.2set

3.3reset

3.4test

4.位图的应用


1.位图的引入

给40亿个不重复的无符号整数,没排过序

再给一个无符号整数,如何快速判断这个无符号整数是否在 这40亿个数中

首先,一个无符号整数占4个字节,40亿个无符号整数占160亿字节

其次,1GB = 1024MB = 1024*1024KB = 1024*1024*1024Byte 约等于 10亿+ 字节

那么40亿个无符号整数需要约16G的内存,超出普通计算机的容量,更别提

使用哈希(指针等额外开销)、排序后二分查找(内存压力未解决)判断,

解决方法:使用位图标记

数据是否在给定的整形数据中,结果是在或者不在,刚好是两种状态,那么可以使用一 个二进制比特位来代表数据是否存在的信息,如果二进制比特位为1,代表存在,为0 代表不存在

2.位图概念

位图就是用比特位表示一个数据的状态信息,适用于海量数据,数据无重复的场景。通常是用来判断某个数据存不存在的

位图就是将数据与数据在位图中对应的比特位进行了一一对应,是哈希的一种变形

3.位图的实现

用字节进行位运算,我们可以操纵某一个比特位为0或者为1

因为位运算操作的是数据的二进制位模式,而非内存中的字节顺序,所以我们不必关注端序

只是在画图的时候需要关注一下端序(大小端)

3.1前提准备

#pragma once
#include<vector>
namespace dfq
{template<size_t N>class bitset{public:bitset(){_a.resize(N / 32 + 1);}private:vector<int> _a;};
}
(1)C++库里面有 bitset 的实现,创建命名空间避免命名冲突
(1)非类型模板参数N表示要开多大的空间
(1)使用一个整型或者char类型的数组,通过字节位运算操纵比特位
(1)构造函数,向上取整开空间

3.2set

//将x映射的那个位置变为1
void set(size_t x)
{size_t i = x / 32;//i标识x映射到_a的第几个位置size_t j = x % 32;//j标识x映射到4个字节中的哪一个位置_a[i] |= (1 << j);
}

(1)  i 标识x映射到_a的第几个位置
(2) j 标识x映射到4个字节中的哪一个位置

(3) 数组中对应数据的对应二进制位变为1

| 或运算的特点,有1为1,0与其他数进行或运算等于其他数本身
<< 左移运算符的特点,数据的二进制为向高位移动,左边舍弃,右边补0

......... 0 ...........   == _a[i]00000000001000000000000   == 1 << j

3.3reset

//将x映射的那个位置变为0
void reset(size_t x)
{size_t i = x / 32;//i标识x映射到_a的第几个位置size_t j = x % 32;//j标识x映射到4个字节中的哪一个位置_a[i] &= ~(1 << j);
}

(1) 数组中对应数据的对应二进制位变为0

& 与运算的特点,有0为0,1与其他数进行与运算等于其他数本身
<< 左移运算符的特点,数据的二进制为向高位移动,左边舍弃,右边补0

~ 按位取反运算特点,数据的二进制位 1 变 0,0变1

......... 1 ...........   == _a[i]00000000001000000000000   == 1 << j11111111110111111111111   == ~(1 << j)

3.4test

bool test(size_t x)
{size_t i = x / 32;//i标识x映射到_a的第几个位置size_t j = x % 32;//j标识x映射到4个字节中的哪一个位置return _a[i] & (1 << j);
}

_a[i] & (1 << j) 的意思是:

数据存在,数组中对应数据的对应比特位为1,表达式不为0,为真

数据不存在,数组中对应数据的对应比特位为0,表达式为0,为假

4.位图的应用

1. 给定100亿个整数,设计算法找到只出现一次的整数?

(1)使用两个位图 bs1、bs2 (根据范围开空间)

(2)从文件中读取数据,调用set函数进行标记,标记原理及规则如下:

bs1、bs2对应的比特位一个有 00、01、10、11四种情况,我们取前面三种

  • 初始条件下,bs1、bs2比特位均为0
  • 数据第一次出现(!_bs1.test(x) && !_bs2.test(x)),bs2.set(x)
  • 数据第二次出现(!_bs1.test(x) && _bs2.test(x)),bs1.set(x);bs2.reset(x)
  • 三次以上就不进行统计了

(3)bs1、bs2对应的比特位组合为01的数就是只出现一次的整数

template<size_t N>
class twobitset
{
public://x映射的那个值变为1void set(size_t x){//00 -> 01if (!_bs1.test(x) && !_bs2.test(x))_bs2.set(x);//01 -> 10else if (!_bs1.test(x) && _bs2.test(x)){_bs1.set(x);_bs2.reset(x);}//10 就不变了}//检测x是否只存在一次bool is_once(size_t x){return !_bs1.test(x) && _bs2.test(x);}private:bitset<N> _bs1;bitset<N> _bs2;
};

2. 给两个文件,分别有100亿个整数,我们只有1G内存,如何找到两个文件交集?

将两个序列分别映射到两个位图上,对两个位图的每个字节进行按位与操作,结果为1 的比特位对应的数据的就是两个序列的交集

3. 位图应用变形:1个文件有100亿个int,1G内存,设计算法找到出现次数不超过2次的所有整 数

与第一题的思路一致,使用两个位图统计次数,00、01、10、11

  • 初始条件下,bs1、bs2比特位均为0
  • 数据第一次出现(!_bs1.test(x) && !_bs2.test(x)),bs2.set(x)
  • 数据第二次出现(!_bs1.test(x) && _bs2.test(x)),bs1.set(x);bs2.reset(x)
  • 数据第三次出现(_bs1.test(x) && !_bs2.test(x)),bs2.set(x)
  • 四次以上就不进行统计了

总结位图的应用:

1. 快速查找某个数据是否在一个集合中

2. 排序 + 去重

3. 求两个集合的交集、并集等

4. 操作系统中磁盘块标记

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

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

相关文章

[iOS] ViewController 的生命周期

文章目录前言一、UIViewController 生命周期有关函数二、UIViewController 中函数的执行顺序运行结果1.present和dismiss2.push和pop三、总结前言 UIViewController 是在 iOS 开发中一个非常重要的角色&#xff0c;他是 view 和 model 的桥梁&#xff0c;通过 UIViewControlle…

第30章 零售与电商AI应用

本章将深入探讨人工智能在零售与电商领域的革命性应用。我们将从智能推荐系统、动态定价、库存管理到创新的虚拟试衣间&#xff0c;全面解析AI如何重塑购物体验和商业运营效率&#xff0c;并为每个关键技术点提供代码实战&#xff0c;帮助你掌握将AI应用于真实商业场景的能力。…

QT通过QModbusRtuSerialMaster读写电子秤数据实例

一、电子称常用功能&#xff1a;称重、清零、去皮&#xff1b;电子秤的通讯方式&#xff1a;Modbus通信、串口通信。二、QT读写电子秤软件界面如下&#xff1a;三、核心代码如下&#xff1a;.pro项目文件代码&#xff1a;QT core gui serialbus serialport.h头文件代码#…

sqlmap常用命令

ZZHow(ZZHow1024) 一、扫描注入点 1.GET方法&#xff0c;给URL&#xff1a; #探测该url是否存在漏洞 python sqlmap.py -u "http://192.168.10.1/sqli/Less-1/?id1"#如果我们已经知道admin这里是注入点的话&#xff0c;可以在其后面加个*来让sqlmap对其注入 python …

JVM如何排查OOM

当JVM&#xff08;Java虚拟机&#xff09;出现OOM&#xff08;OutOfMemoryError&#xff09;时&#xff0c;可以按照以下步骤和方法&#xff0c;用于帮助定位和解决JVM中的OOM问题1.查看异常堆栈信息查看异常堆栈信息&#xff08;StackTrace&#xff09;是定位问题的关键。OOM异…

存算一体芯片生态评估:从三星PIM到知存科技WTM2101

点击 “AladdinEdu&#xff0c;同学们用得起的【H卡】算力平台”&#xff0c;注册即送-H卡级别算力&#xff0c;80G大显存&#xff0c;按量计费&#xff0c;灵活弹性&#xff0c;顶级配置&#xff0c;学生更享专属优惠。 引言&#xff1a;存算一体技术的崛起与意义 在传统冯诺…

[数据结构] 栈 · Stack

一.栈 stack 1.概念 栈 : 一种特殊的线性表 , 其只允许再固定的一段进行插入和删除元素操作 进行数据插入和删除操作的一段称为 栈顶 ; 另一端称为栈底栈中的数据元素遵循 先进后出 原则(LIFO)压栈 : 栈的插入操作叫做 进栈 或 压栈 或 入栈 , 入数据在栈顶出栈 : 栈的删除…

MySQL执行过程中如何选择最佳的执行路径

本篇文章介绍一个非常核心的数据库问题。MySQL 选择最佳执行路径&#xff08;即“查询优化”&#xff09;的过程是由其查询优化器&#xff08;Query Optimizer&#xff09; 完成的。 简单来说&#xff0c;优化器的目标是&#xff1a;在多种可能的执行方案中&#xff0c;选择一个…

【设计模式】从游戏角度开始了解设计模式 --- 抽象工厂模式

永远记住&#xff0c;你的存在是有意义的&#xff0c; 你很重要&#xff0c; 你是被爱着的&#xff0c; 而且你为这个世界带来了无可取代的东西。 -- 麦克西 《男孩、鼹鼠、狐狸和马》-- 从零开始了解设计模式抽象工厂模式抽象工厂模式 今天我们一起来探究抽象工厂模式&#x…

tensorflow.js 使用场景

TensorFlow.js (简称 TF.js) 是一个利用 WebGL 和 Node.js 在浏览器和服务器端进行机器学习模型训练和部署(推理)的 JavaScript 库。它的核心价值在于将机器学习的能力带入了 Web 开发者和 JavaScript 生态的领域。 其主要应用场景可以分为以下几大类: 一、在浏览器中直接进…

详解mcp以及agen架构设计与实现

文章目录1.MCP概念2.MCP服务端主要能力3.MCP技术生态4.MCP与Function call区别5.MCP生命周期6.MCP java SDK7.MCP应用场景8.基于springAIollma阿里qianwenmcp设计私有AIAgent应用实现9.AI java项目落地技术选型10.构建AI Agent四大模块11.LLM(大模型)与MCP之间关系12.A2A、MCP、…

六级第一关——下楼梯

上目录&#xff1a; 目录 题目描述 输入格式 输出格式 输入输出样例 说明/提示 一、DP的意义以及线性动规简介 在一个困难的嵌套决策链中&#xff0c;决策出最优解。 二、动态规划性质浅谈 三、子序列问题 &#xff08;一&#xff09;一个序列中的最长上升子序列&am…

【Linux基础】Linux系统配置IP详解:从入门到精通

目录 1 Linux网络配置概述 2 网卡配置文件位置和命名规则 2.1 配置文件位置 2.2 网卡命名规则 2.3 配置文件命名示例 3 网卡配置文件详解 3.1 主要参数说明 4 Linux系统配置IP步骤 4.1 DHCP动态配置 4.2 静态IP配置 5 Linux网络配置流程 5.1 网络配置流程 5.2 网卡…

C语言sprintf的高效替代方案

C语言的sprintf和snprintf将变量格式化输出到内存buffer&#xff0c;其功能强大&#xff0c;用起来很方便。但sprintf系列函数的运行效率低下&#xff0c;主要包括四方面的原因&#xff1a;格式字符串解析、变参处理、locale&#xff08;本地化&#xff09;支持和通用&#xff…

【知识堂】制造业与物流数字化全景图:系统缩写大全与专业名词速查手册

前言在制造业和物流行业的数字化转型过程中&#xff0c;我们经常会接触到大量的 系统缩写&#xff08;如 ERP、MES、WMS…&#xff09;和 专业名词&#xff08;如 AGV、BOM、LOT…&#xff09;。 这些缩写往往让刚入行的人“一头雾水”&#xff0c;即使是有经验的从业者&#x…

利用JSONCrack与cpolar提升数据可视化及跨团队协作效率

文章目录前言1. 在Linux上使用Docker安装JSONCrack2. 安装Cpolar内网穿透工具3. 配置JSON Crack界面公网地址4. 远程访问 JSONCrack 界面5. 固定 JSONCrack公网地址前言 JSONCrack 是一款功能强大的开源数据可视化工具&#xff0c;专为解析和展示复杂的 JSON、XML 等结构化数据…

CANoe入门之一 CANoe功能概述

01 CANoe功能概述 CANoe软件在汽车电子领域被广泛应用。 CANoe软件的全称是CAN Open Environment&#xff0c;它是一个专业的系统级总线和ECU仿真、分析、开发、测试工具。支持ECU或总线网络开发从需求分析到系统实现的全过程&#xff0c;包括模型创建、仿真、测试、诊断及通信…

项目管理核心八项(软件篇)

2025年09月11日23:50:33&#xff1a;进来常思&#xff0c;写代码也五六年了&#xff0c;后面的路该何去何从呢&#xff1f; 项目管理核心八项一、项目管理之“建立开发人员 backup 机制”二、待补充一、项目管理之“建立开发人员 backup 机制” “建立开发人员 backup 机制” 是…

springboot redisson 分布式锁入门与实战

Spring Boot3 Redisson 项目地址 https://gitee.com/supervol/loong-springboot-study &#xff08;记得给个start&#xff0c;感谢&#xff09; Redisson 介绍 在分布式系统中&#xff0c;多节点部署的应用对共享资源&#xff08;如数据库记录、缓存键、文件&#xff09;的…

使用 Tkinter + Requests 实现地理信息安全系统学习时长助手

✨重磅&#xff01;盹猫的个人小站正式上线啦&#xff5e;诚邀各位技术大佬前来探秘&#xff01;✨ 这里有&#xff1a; 硬核技术干货&#xff1a;编程技巧、开发经验、踩坑指南&#xff0c;带你解锁技术新姿势&#xff01;趣味开发日常&#xff1a;代码背后的脑洞故事、工具…