哈希应用之位图

文章目录

  • 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.xdnf.cn/news/150031.html

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

相关文章

假期AI新闻热点:亚运会Al技术亮点;微软GPT-4V论文精读;Perplexity推出pplx-api;DALL-E 3多渠道测评 | ShowMeAI日报

&#x1f440;日报&周刊合集 | &#x1f3a1;生产力工具与行业应用大全 | &#x1f9e1; 点赞关注评论拜托啦&#xff01; &#x1f525; 科技感拉满&#xff0c;第19届杭州亚运会中的Al技术亮点 八年筹备&#xff0c;杭州第19届亚运会开幕式于9月23日晚隆重举行&#xff0…

vue3中使用return语句返回this.$emit(),在同一行不执行,换行后才执行,好奇怪!

今天练习TodoList任务列表案例,该案例效果如图所示&#xff1a; 此案例除了根组件App.vue&#xff0c;还有TodoList、TodoInput、TodoButton三个子组件。 因为有视频讲解&#xff0c;在制作TodoList、TodoInput时很顺利&#xff0c;只是在完成TodoButton这个组件时出了点问题…

<二>Qt斗地主游戏开发:过场动画的实现

1. 过场动画效果 2. 思路分析 过场动画较为简单&#xff0c;只有一个进度条在进行滚动&#xff0c;因此实现起来不需要动画相关处理&#xff0c;仅需要图片和定时器设定&#xff0c;让进度条动起来即可。我们可以创建一个对话框&#xff0c;设定背景图片以及对话框透明无边框&a…

口袋参谋:如何有效地监测你的竞争对手!

​在淘宝天猫上开店&#xff0c;竞争是非常大的&#xff0c;那么就会出现许多同样的产品&#xff0c;如果想要在竞争中胜出&#xff0c;就需要多去研究同行的数据&#xff0c;知己知彼&#xff0c;百战百胜。 掌握竞争对手数据目的主要是有2个&#xff1a; 1、掌握对手是怎么起…

操作符 | C语言中操作符详解 | 操作符的优先级 | 移位操作法的使用方式

一、算术操作符&#xff1a;、-、*、/、% 算术操作符其实在平时生活中&#xff0c;也遇到很多&#xff0c;并且这五类操作符基本很常见&#xff0c;而他们的作用与数学所学习的功能是一样的。但是“/”除号操作符与“%”取模操作符有些不同。下面就以这两个的操作符为主要说起…

伟大不能被计划

假期清理书单&#xff0c;把这个书读完了&#xff0c;结果发现出奇的好&#xff0c;可以说是值得亲身去读的书&#xff0c;中间的一些论述提供了人工智能专业方面的视角来论证这这个通识观点&#xff0c;可信度很不错&#xff1b; 这篇blog也不是对书的总结&#xff0c;更多的是…

asp.net班级管理系统VS开发sqlserver数据库web结构c#编程Microsoft Visual Studio

一、源码特点 asp.net班级管理系统 是一套完善的web设计管理系统&#xff0c;系统具有完整的源代码和数据库&#xff0c;系统主要采用B/S模式开发。开发环境为vs2010&#xff0c;数据库为sqlserver2008&#xff0c;使用c#语言开发 asp.net班级管理系统 二、功能介绍 1…

Pikachu靶场——目录遍历漏洞和敏感信息泄露

文章目录 1. 目录遍历漏洞1.1 源码分析1.2 漏洞防御 2. 敏感信息泄露2.1 漏洞防御 1. 目录遍历漏洞 漏洞描述 目录遍历漏洞发生在应用程序未能正确限制用户输入的情况下。攻击者可以利用这个漏洞&#xff0c;通过在请求中使用特殊的文件路径字符&#xff08;如 …/ 或 %2e%2e…

Electronjs入门-Electron中的主要模块

在本节中&#xff0c;我们将了解在Electron中创建任何应用程序时的一些基本模块&#xff1b;这些模块多种多样&#xff0c;使我们能够轻松地进行进程通信&#xff0c;创建操作系统的本地菜单。 为了利用Electron模块&#xff0c;以及任何第三方或Node模块&#xff0c;不仅在主流…

SSM - Springboot - MyBatis-Plus 全栈体系(二十一)

第四章 SpringMVC 四、RESTFUL 风格设计和实战 1. RESTFul 风格概述 1.1 RESTFul 风格简介 RESTful&#xff08;Representational State Transfer&#xff09;是一种软件架构风格&#xff0c;用于设计网络应用程序和服务之间的通信。它是一种基于标准 HTTP 方法的简单和轻量…

visual studio解决bug封装dll库

1.速度最大化 O2 2.设置输出目录 配置属性/常规/输出目录 链接器/常规/输出dll文件 链接器/调试/输出程序数据库pdb文件 链接器/高级/导入库 3.输出X86 X64分别对应的dll、lib、pdb 然后修改更新说明 更新说明格式如下&#xff1a; 4.将库提交到FTP每日更新库文档下 和测试交接…

[NISACTF 2022]hardsql - quine注入

题目描述&#xff1a;$password$_POST[passwd]; $sql"SELECT passwd FROM users WHERE usernamebilala and passwd$password;"; 从描述看出是quine注入&#xff0c;且用户名要是bilala 1、经测试&#xff0c;参数为&#xff1a;username&passwd&login登录&a…

36.骑士周游算法及其基于贪心算法的优化

概述 骑士周游算法&#xff0c;叫做“马踏棋盘算法”或许更加直观。在国际象棋8x8的棋盘中&#xff0c;马也是走“日字”进行移动&#xff0c;相应的产生了一个问题&#xff1a;“如果要求马 在每个方格只能进入一次&#xff0c;走遍全部的64个方格需要如何行进&#xff1f;”…

1147. 段式回文

链接&#xff1a; ​​​​​​1147. 段式回文 题解&#xff1a; class Solution { public:int longestDecomposition(string text) {MOD 1e9 7;if (text.size() < 0) {return 0;}// 初始化26的n次方的表pow26.resize(text.size());pow26[0] 1;for (int i 1; i < …

【C语言】利用数组处理批量数据(字符数组)

前言:前面已经介绍了&#xff0c;字符数据是以字符的ASCII代码存储在存储单元中的&#xff0c;一般占一个字节。由于ASCII代码也属于整数形式&#xff0c;因此在C99标准中&#xff0c;把字符类型归纳为整型类型中的一种。 &#x1f496; 博主CSDN主页:卫卫卫的个人主页 &#x…

数据结构——红黑树(详解性质+C++模拟)

文章目录 前言红黑树的概念红黑树的性质红黑树结点的定义红黑树的插入操作1. **按照二叉搜索树的规则插入新结点**2. 检测新节点插入后&#xff0c;红黑树的性质是否遭到破坏 红黑树的验证总结 前言 本篇博客将为大家重点讲述红黑树这一数据结构&#xff0c;讲解其实现的方式即…

One Thread One Loop主从Reactor模型⾼并发服务器

One Thread One Loop主从Reactor模型⾼并发服务器 文章目录 One Thread One Loop主从Reactor模型⾼并发服务器一些补充HTTP服务器Reactor 模型eventfd通用类Any 目标功能模块划分&#xff1a;SERVER模块Buffer模块&#xff1a;编写思路&#xff1a;接口设计&#xff1a;具体实现…

毕设-原创医疗预约挂号平台分享

医疗预约挂号平台 不是尚医通项目&#xff0c;先看项目质量&#xff08;有源码论文&#xff09; 项目链接&#xff1a;医疗预约挂号平台git地址 演示视频&#xff1a;医疗预约挂号平台 功能结构图 登录注册模块&#xff1a;该模块具体分为登录和注册两个功能&#xff0c;这些…

Linux:环境变量、地址空间

目录 一、环境变量 1、什么是环境变量 2、常见的环境变量 3、环境变量相关命令 二、地址空间 1、进程地址空间 2、虚拟地址空间 一、环境变量 1、什么是环境变量 首先先举个环境变量的例子&#xff1a; 我们在Linux中&#xff0c;运行ls、pwd之类的命令&#xff0c;直…

力扣 -- 873. 最长的斐波那契子序列的长度

解题步骤&#xff1a; 参考代码&#xff1a; class Solution { public:int lenLongestFibSubseq(vector<int>& nums) {int nnums.size();unordered_map<int,int> hash;for(int i0;i<n;i){hash[nums[i]]i;}int ret2;vector<vector<int>> dp(n,v…