哈希应用之位图

文章目录

  • 1.位图概念
  • 2.面试题引入
  • 3.代码解决[配注释]
  • 4.位图应用
    • 4.1找到100亿个整数里只出现一次的整数
    • 4.2找两个分别有100亿个整数的文件的交集[只有1G内存]
      • 1.法一[使用于数据量<=42亿]
      • 2.法二[适用于数据量大>42亿]
      • 3.在一个有100亿个int的文件中找到出现次数不超过2次的所有整数[1G内存]
  • 5.优劣分析
    • 优点
    • 缺点

在这里插入图片描述

1.位图概念

位图,用每一位来存放某种状态,适用于海量数据数据无重复的场景。通常是用来判断某个数据是否存在于海量数据.

2.面试题引入

例如: 经典面试题[腾讯]

现在有40亿个不重复的无符号整数,没排过序。如何快速判断一个无符号整数是否在这40亿个数中。

思考:

1.暴力查找 40亿次
2.排序+二分 最优排序O(N*logN) 二分logN [且二分查找要支持下标访问 文件无法下标查找]
3.哈希表/红黑树 使用的前提是数据在它里面 而40亿整数大小为16G 无法使用

怎么办???面试要挂了吗???要与大厂失之交臂了吗???
不!我要进大厂!那就往下学一下位图!!!

一个无符号整数X是否在给定的整形数据中,需要得到的结果是在或者不在,是两种状态,可以使用一个二进制比特位来代表数据是否存在,假定二进制比特位为1,代表存在,为0代表不存在。这样一个字节8个比特位可以存储8个整数 40亿个整数需要多大空间呢?容易得到的是1G=10亿字节=80亿比特位 一个比特位存储一个整数 40亿个整数需要40亿个比特位 即0.5G

3.代码解决[配注释]

在这里插入图片描述
在这里插入图片描述

//一个比特位变标识两种状态 0 1
template<size_t N>
class bitmap
{
public://构造函数bitmap() {//开空间 初始化成0_bits.resize(N / 8 + 1, 0);} //插入: 将数x映射的位 置成1void insert_setone(size_t x){//第i个字节  0 1 2 3 ...size_t i = x / 8;//第i个字节的第j个位size_t j = x % 8;//利用或等 第j位-置1 其余位-不变  _bits[i] |= (1 << j);  //左移:并不是向左移而是向高位移} //删除: 将数x映射的位 置成0void erase_setzero(size_t x){//第i个字节  0 1 2 3 ...size_t i = x / 8;//第i个字节的第j个位size_t j = x % 8;//利用与等 第j位-置0 其余位-不变 _bits[i] &= ~(1 << j);}//判断: 判断数x是否存在 bool judge(size_t x){//第i个字节  0 1 2 3 ...size_t i = x / 8;//第i个字节的第j个位size_t j = x % 8;//假定数x存在 那么第j位应为1//_bits[i]访问到的是 数x所在第i个字节的整体数return _bits[i] & (1 << j);}private:vector<char> _bits;
}; 测试函数 ///void test_bitmap1()
{bitmap<100> bm;bm.insert_setone(10);bm.insert_setone(11);bm.insert_setone(15);cout << bm.judge(10) << endl;cout << bm.judge(15) << endl;bm.erase_setzero(10);cout << bm.judge(10) << endl;cout << bm.judge(15) << endl;bm.erase_setzero(10);bm.erase_setzero(15);cout << bm.judge(10) << endl;cout << bm.judge(15) << endl;
}void test_bitmap2()
{//4294967295//bitset<-1> bm;bitmap<0xFFFFFFFF> bm;
}

4.位图应用

4.1找到100亿个整数里只出现一次的整数

///  找到100亿个整数里只出现一次的整数 
//两个比特位变标识三种状态 00-不存在 01-存在一个 10-存在多个
template<size_t N>
class double_bitmap
{
public://插入函数 -- 映射位置1void insert_setone(size_t x){//数x 第一次进来定走这个if// 00 -> 01 原无此数 现有一次if (_left.judge(x) == false&& _right.judge(x) == false){//_right映射位 置1_right.insert_setone(x);}//第二次又来了一个相同数x 走这个else if// 01 -> 10  原有一次 现有两次 else if (_left.judge(x) == false&& _right.judge(x) == true){//_left映射位 置1//_right映射位 置0_left.insert_setone(x);_right.erase_setzero(x);} //10 :存在多个的数 不用处理 10是多个 再插入一个 还是多个 10}//输出只存在一次的数void Print(){for (size_t i = 0; i < N; ++i){if (_right.judge(i))cout << i << endl;}}public:bitmap<N> _left;bitmap<N> _right;
};///  测试函数  void test_doublebitmap()
{int a[] = { 3, 45, 53, 32, 32, 43, 3, 2, 5, 2, 32, 55, 5, 53, 43, 9, 8, 7, 8 };double_bitmap<100> double_bm;for (auto e : a){double_bm.insert_setone(e);}double_bm.Print();
}

4.2找两个分别有100亿个整数的文件的交集[只有1G内存]

1.法一[使用于数据量<=42亿]

N+N

时间复杂度与数据个数有关

Step1:将文件一的数据以位图一存储
Sterp2:将文件二的数据一一读取 调用judge函数 判断是否存在于文件一的位图中 若存在 则是交集 将位图一对应位 置成0[当前数已被认定是交集 为防止文件二有重复值 下个与当前数相同的数再来judge时 认定为不存在—去重]

2.法二[适用于数据量大>42亿]

2N+42亿

时间复杂度还与N有关[2^32-1]
计算机知识:计算机所能存储的最大整数:int 在32位机器下 int是4个字节 32个bit 2^32-1

Step1:将文件一的数据映射到位图一
Step2:将文件二的数据映射到位图二
Step3:遍历N[因为100亿个数可能存在计算机所能够存储的42亿个整数里的任意一个 所以要遍历42亿个bit
位] 若两个位图对应位均为1 则为交集

3.在一个有100亿个int的文件中找到出现次数不超过2次的所有整数[1G内存]

用两个bit来标识即可
00:出现0次
01:出现1次
10:出现2次
11:出现2次及以上

5.优劣分析

优点

时间复杂度 空间复杂度小

缺点

只能映射整型 浮点数\string不能用位图

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

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

相关文章

AI伦理:如何确保人工智能的公平与透明

文章目录 什么是AI伦理&#xff1f;AI公平性AI透明性 为什么AI公平性和透明性重要&#xff1f;确保AI公平性的方法1. 数据收集和准备2. 算法和模型3. 解释和可解释性4. 持续监测 确保AI透明性的方法1. 记录决策2. 可解释性工具3. 用户教育 AI伦理的挑战和未来结论 &#x1f389…

STM32MP157汇编流水灯

.text .global _start _start: /* 使能GPIOE、GPIOF寄存器 RCC_MP_AHB4ENSETR * 基地址: 0x50000000 偏移地址: 0xA28 0x50000A28* RCC_MP_AHB4ENSETR[4]->1 RCC_MP_AHB4ENSETR[5]->1*/ LDR R0,0x50000A28LDR R1,[R0]ORR R1,R1,#(0x1<<4)STR R1,[R0]LDR R0,0x…

C++ 学习系列 -- std::list

一 std::list 介绍 list 是 c 中的序列式容器&#xff0c;其实现是双向链表&#xff0c;每个元素都有两个指针&#xff0c;分别指向前一个节点与后一个节点 链表与数组都是计算机常用的内存数据结构&#xff0c;与数组连续内存空间不一样的地方在于&#xff0c;链表的空间是不…

【Java 进阶篇】HTML块级元素详解

HTML&#xff08;Hypertext Markup Language&#xff09;是用于创建网页的标记语言。在HTML中&#xff0c;元素被分为块级元素和内联元素两种主要类型。块级元素通常用于构建网页的结构&#xff0c;而内联元素则嵌套在块级元素内&#xff0c;用于添加文本和其他内容。本文将重点…

异常:找不到匹配的key exchange算法

目录 问题描述原因分析解决方案 问题描述 PC 操作系统&#xff1a;Windows 10 企业版 LTSC PC 异常软件&#xff1a;XshellPortable 4(Build 0127) PC 正常软件&#xff1a;PuTTY Release 0.74、MobaXterm_Personal_23.1 服务器操作系统&#xff1a;OpenEuler 22.03 (LTS-SP2)…

Ubuntu 22.04 安装系统 手动分区 针对只有一块硬盘 lvm 单独分出/home

自动安装的信息 参考自动安装时产生的分区信息 rootyeqiang-MS-7B23:~# fdisk /dev/sdb -l Disk /dev/sdb&#xff1a;894.25 GiB&#xff0c;960197124096 字节&#xff0c;1875385008 个扇区 Disk model: INTEL SSDSC2KB96 单元&#xff1a;扇区 / 1 * 512 512 字节 扇区大…

phpstudy本地域名伪静态

环境&#xff1a;WNMP(Windows10 Nginx1.15.11 MySQL5.7.26 【PHP 7.4.3 (cli) (built: Feb 18 2020 17:29:57) ( NTS Visual C 2017 x64 ) 】) 使用PhpStudy配置本地域名后&#xff0c;设置伪静态&#xff0c;这样在Web端打开网站就不需要输入index.php了&#xff0c;很简单…

架构方法、模型、范式、治理

从架构方法、模型、范式、治理等四个方面介绍架构的概念和方法论、典型业务场景下的架构范式、不同架构的治理特点这3个方面的内容

Pycharm操作git仓库 合并等

菜单 Git CommitPushUpdate ProjectPullFetchMergreRebase 查询 查询分支 查询本地所有分支 # 查询本地分支 git branch# 查询远程分支 git branch -rPycharm查看当前分支 步骤&#xff1a; Git->Branches 哈喽&#xff0c;大家好&#xff0c;我是[有勇气的牛排]&…

ELK集群 日志中心集群

ES&#xff1a;用来日志存储 Logstash:用来日志的搜集&#xff0c;进行日志格式转换并且传送给别人&#xff08;转发&#xff09; Kibana:主要用于日志的展示和分析 kafka Filebeat:搜集文件数据 es-1 本地解析 vi /etc/hosts scp /etc/hosts es-2:/etc/hosts scp /etc…

视频转GIF:快速生成有趣的动态图片

随着社交媒体的快速发展&#xff0c;GIF动态图片已经成为了人们表达情感、分享生活片段的重要方式。将视频片段转换成GIF动态图片&#xff0c;可以让人们更好地分享和表达自己的情感&#xff0c;也可以让一些有趣的瞬间变得更加生动有趣。本文将介绍如何将视频快速转换成GIF动态…

微信小程序wxs标签 在wxml文件中编写JavaScript逻辑

PC端开发 可以在界面中编写JavaScript脚本 vue/react这些框架更是形成了一种常态 因为模板引擎和jsx语法本身就都是在js中的 我们小程序中其实也有类似的奇妙写法 不过先声明 这东西不是很强大 我们可以先写一个案例代码 wxml代码参考 <view><wxs module"wordSt…

Mac 点击桌面 出现黑边框 解决

1、桌面黑框效果 2、解决&#xff1a;设置为 仅在台前调度中

数据结构-顺序存储二叉树

文章目录 目录 文章目录 前言 一 . 什么是顺序存储二叉树 二 . 模拟实现 前序遍历 总结 前言 大家好,今天给大家讲一下顺序存储二叉树 一 . 什么是顺序存储二叉树 顺序存储二叉树是一种将二叉树的节点按照从上到下、从左到右的顺序存储在数组中的方法。具体来说&#xff0c;顺…

文件操作 和 IO - 详解

一&#xff0c;认识文件 1.1 树形结构组织和目录 文件是对于"硬盘"数据的一种抽象&#xff0c;在一台计算机上&#xff0c;有非常多的文件&#xff0c;这些文件是通过 "文件系统" 来进行组织的&#xff0c;本质上就是通过 "目录"(文件夹) 这样…

WebGoat 靶场 JWT tokens 四 五 七关通关教程

文章目录 webGoat靶场第 四 关 修改投票数第五关第七关 你购买书&#xff0c;让Tom用户付钱 webGoat靶场 越权漏洞 将webgoat-server-8.1.0.jar复制到kali虚拟机中 sudo java -jar webgoat-server-8.1.0.jar --server.port8888解释&#xff1a; java&#xff1a;这是用于执行…

MySQL命令行中文乱码问题

MySQL命令行中文乱码问题&#xff1a; 命令行界面默认字符集是gbk&#xff0c;若字符集不匹配会中文乱码或无法插入中文。 解决办法&#xff1a;执行set names gbk; 验证&#xff1a; 执行命令show variables like ‘char%’;查看默认字符集。 创建数据库设置字符集utf8&…

2023旅游产业内容营销洞察报告:如何升级经营模式,适配社媒新链路

2023年我国旅游业强劲复苏&#xff0c;上半年旅游消费增长显著&#xff0c;政府出台一系列文旅扶持政策后&#xff0c;旅游业也在积极寻求数字化转型的升级方式。 上半年以旅游消费为代表的服务业对经济的增长贡献率超过60%&#xff0c;旅游企业普遍实现经营好转&#xff0c;企…

【FPGA零基础学习之旅#14】串口发送字符串

&#x1f389;欢迎来到FPGA专栏~串口发送字符串 ☆* o(≧▽≦)o *☆嗨~我是小夏与酒&#x1f379; ✨博客主页&#xff1a;小夏与酒的博客 &#x1f388;该系列文章专栏&#xff1a;FPGA学习之旅 文章作者技术和水平有限&#xff0c;如果文中出现错误&#xff0c;希望大家能指正…

电脑散热——液金散热

目录 1.简介 2.传统硅脂与液金导热区别 3.特点 4.优点 5.为什么液金技术名声不太好 6.使用方法 1.简介 凡是对于电脑基础硬件有所了解的人&#xff0c;都知道硅脂是如今高性能电脑设备中必不可少的东西。芯片表面和散热器接触面&#xff0c;虽然肉眼看上去是非常光滑的金属…