C++进阶--位图和布隆过滤器

位图和布隆过滤器是两种常用的数据结构,它们在计算机科学领域有着广泛的应用。本文将介绍这两种数据结构的基本原理和应用场景。

位图

前提

在这里插入图片描述

位图的概念

位图(Bitmap)是一种用于表示集合的数据结构,它将每个元素映射为一个位(bit),以表示其存在或不存在。在位图中,通常使用一个数组来存储位,其中数组的每个元素代表一个位。

位图的基本思想是,对于给定的集合,为每个元素定义一个唯一的编号或索引。根据这个编号,将位图中的相应位置设置为1或0,表示元素的存在与否。例如,如果一个集合有100个元素,可以用一个长度为100的位数组来表示这个集合,其中每个元素的位置代表相应元素的编号,位置上的位值表示该元素是否存在。如果位值为1,表示元素存在;如果位值为0,表示元素不存在。

由于位图使用的是位操作,可以节省大量的内存空间。相比传统的存储方式,位图所需的内存空间较小。这使得位图在许多领域都有广泛的应用,特别是当需要快速判断元素是否存在于集合中时。

位图的实现

template<size_t N>class bitset{public:bitset(){_bits.resize(N / 32 + 1, 0);}//把x的映射位标记为1void set(size_t x){assert(x <= N);size_t i = x / 32;size_t j = x % 32;//通过或运算,将对应位变为1_bits[i] |= (1 << j);}//把x映射的标记为0void reset(size_t x){assert(x <= N);size_t i = x / 32;size_t j = x % 32;//通过与运算,将对应位变为0,~将数倒置_bits[i] &= ~(1 << j);}//判断当前x映射的位置是否为1bool test(size_t x){assert(x <= N);size_t i = x / 32;size_t j = x % 32;//如果存在,就会返回一个非0的数;return _bits[i] & (1 << j);}private:vector<int> _bits;};

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
测试:

void Test1(){bitset<150> bs1;bs1.set(50);bs1.set(101);bs1.set(89);for (size_t i=0; i < 150; i++){if (bs1.test(i)){cout << i << "->" << "在" << "  ";}else{cout << i << "->" << "不在" << "  ";}}cout << endl;bs1.reset(89);if (bs1.test(89)){cout << 89<< "->" << "在" << endl;}else{cout << 89 << "->" << "不在" << endl;}}

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

位图的应用拓展

在这里插入图片描述

template<size_t N>class two_bit_set{public:void set(size_t x){if (_bs1.test(x) == false && _bs2.test(x) == false){//00->01_bs2.set(x);}else if (_bs1.test(x) == false && _bs2.test(x) == true){//01->10_bs2.reset(x);_bs1.set(x);}}bool test(size_t x){if (_bs1.test(x) == false&& _bs2.test(x) == true){return true;}return false;}private:bitset<N> _bs1;bitset<N> _bs2;};

在这里插入图片描述
在这里插入图片描述
位图常用于数据压缩、数据库索引、图像处理等领域。在数据压缩中,位图可以将大量的数据压缩成较小的文件,这在网络传输和存储空间方面有着重要的作用。在数据库索引中,位图可以快速定位到包含某个元素的记录,提高检索效率。在图像处理中,位图可以对图像进行像素级别的操作,实现各种图像处理功能。

布隆过滤器

前提

对于位图来说,只能处理整数类型的元素,如果遇到字符串的话,如果只通过一个哈希函数来计算对应的哈希值,那么在位图中很大概率会存在相同的索引(哈希值),这样就导致了重复;所以,就有人提出了通过多个哈希函数对key值进行不同位置的映射,这样就能让重复的概率大大降低,当然没有办法百分百避免。

概念

布隆过滤器(Bloom Filter)是一个数据结构,用于快速判断一个元素是否属于某个集合中。它利用了一系列随机映射函数和一个二进制向量来实现。

具体而言,布隆过滤器由一个长度为m的二进制向量(bit数组)和k个不同的哈希函数组成。初始时,所有的位都被置为0

当一个元素要被添加到布隆过滤器中时,会将该元素经过k个不同的哈希函数计算得到k个哈希值,并将对应的位置在二进制向量中置为1。

当需要判断一个元素是否在布隆过滤器中时,同样将该元素经过k个哈希函数计算得到k个哈希值,并检查对应的位置在二进制向量中是否都为1。如果有任何一个位置不为1,则可以确定该元素不在集合中。但如果所有位置都为1,那么该元素可能在集合中,但也可能是误判。

因此,布隆过滤器存在一定的误判率。当哈希函数的选取和位向量的大小合理时,误判率可以被控制在一个较低的范围内。
在这里插入图片描述

布隆过滤器的实现

struct HashFuncBKDR
{size_t operator()(const string& s){size_t hash = 0;for (auto ch : s){hash *= 131;hash += ch;}return hash;}
};struct HashFuncAP
{size_t operator()(const string& s){size_t hash = 0;for (size_t i = 0; i < s.size(); i++){if ((i & 1) == 0)//偶数位字符{hash ^= ((hash << 7) ^ (s[i]) ^ (hash >> 3));}else//奇数位字符{hash ^= (~((hash << 11) ^ (s[i]) ^ (hash >> 5)));}}return hash;}
};struct HashFuncDJB
{size_t operator()(const string& s){size_t hash = 5381;for (auto ch : s){hash = hash * 33 ^ ch;}return hash;}
};template<size_t N,class K=string,class Hash1=HashFuncBKDR,class Hash2=HashFuncAP,class Hash3=HashFuncDJB>
class BloomFilter
{
public:void Set(const K& key){//Hash2 hs2;size_t hash1 = Hash1()(key) % M;size_t hash2 = Hash2()(key) % M;size_t hash3 = Hash3()(key) % M;//cout << hash1 << " " << hash2 << " " << hash3 << endl;_bs.set(hash1);_bs.set(hash2);_bs.set(hash3);}bool Test(const K& key){size_t hash1 = Hash1()(key) % M;if (_bs.test(hash1) == false)return false;size_t hash2 = Hash2()(key) % M;if (_bs.test(hash2) == false)return false;size_t hash3 = Hash3()(key) % M;if (_bs.test(hash3) == false)return false;return true;}
private:static const size_t M = 10 * N;fnc::bitset<M> _bs;
};

在这里插入图片描述
布隆过滤器不能直接支持删除工作,因为在删除一个元素时,可能会影响其他元素。
在这里插入图片描述

性能测试

//性能测试
void TestBF2()
{srand(time(0));const size_t N = 100000;BloomFilter<N> bf;std::vector<std::string> v1;std::string url = "https://www.cnblogs.com/-clq/archive/2012/05/31/2528153.html";for (size_t i = 0; i < N; ++i){v1.push_back(url + std::to_string(i));}for (auto& str : v1){bf.Set(str);}// v2跟v1是相似字符串集(前缀一样),但是后缀不一样std::vector<std::string> v2;for (size_t i = 0; i < N; ++i){std::string urlstr = url;urlstr += std::to_string(9999999 + i);v2.push_back(urlstr);}size_t n2 = 0;for (auto& str : v2){if (bf.Test(str)) // 误判{++n2;}}cout << "相似字符串误判率:" << (double)n2 / (double)N << endl;// 不相似字符串集  前缀后缀都不一样std::vector<std::string> v3;for (size_t i = 0; i < N; ++i){string url = "zhihu.com";url += std::to_string(i + rand());v3.push_back(url);}size_t n3 = 0;for (auto& str : v3){if (bf.Test(str)){++n3;}}cout << "不相似字符串误判率:" << (double)n3 / (double)N << endl;
}

在这里插入图片描述

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

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

相关文章

Java八股文(JVM)

Java八股文のJVM JVM JVM 什么是Java虚拟机&#xff08;JVM&#xff09;&#xff1f; Java虚拟机是一个运行Java字节码的虚拟机。 它负责将Java程序翻译成机器代码并执行。 JVM的主要组成部分是什么&#xff1f; JVM包括以下组件&#xff1a; ● 类加载器&#xff08;ClassLoa…

MySQL 数据库的日志管理、备份与恢复

一. 数据库备份 1.数据备份的重要性 备份的主要目的是灾难恢复。 在生产环境中&#xff0c;数据的安全性至关重要。 任何数据的丢失都可能产生严重的后果。 造成数据丢失的原因&#xff1a; 程序错误人为,操作错误,运算错误,磁盘故障灾难&#xff08;如火灾、地震&#xff0…

【漏洞分析】浅析android手游lua脚本的加密与解密(二)

反编译本人用到的是luajit-decomp,这里需要注意,luajit-decomp默认的lua版本为5.1,luajit版本为2.0.2,我们需要下载对应lua和luajit的版本,编译后替换luajit-decomp下的lua51.dll、luajit.exe、jit文件夹。反编译时需要注意的文件和文件夹: 这里需要下载版本为2.1.0-bet…

AJAX-项目优化(目录、基地址、token、请求拦截器)

目录管理 基地址存储 在utils/request.js配置axios请求基地址 作用&#xff1a;提取公共前缀地址&#xff0c;配置后axios请求时都会baseURLurl 填写API的公共前缀后&#xff0c;将js文件导入到html文件中 <script src"../../utils/request.js"></script&…

【IntelliJ IDEA】运行测试报错解决方案(附图)

IntelliJ IDEA 版本 2023.3.4 (Ultimate Edition) 测试报错信息 命令行过长。 通过 JAR 清单或通过类路径文件缩短命令行&#xff0c;然后重新运行 解决方案 修改运行配置&#xff0c;里面如果没有缩短命令行&#xff0c;需要再修改选项里面勾选缩短命令行让其显示&#x…

【HTTP完全注解】一些神奇的URL

URL HTTP 请求的内容被称为"资源"&#xff0c;‘资源’这一概念非常宽泛&#xff0c;它可以是一份文档&#xff0c;一张图片&#xff0c;或所有其他你能够想到的格式。每个资源的名称和位置由一个 URL&#xff08;统一资源定位符&#xff0c;它是 URI 的一种&#x…

GT收发器第一篇_总体结构介绍

文章目录 前言GT收发器介绍 前言 之前写过一篇简单介绍GT的文章https://blog.csdn.net/m0_56222647/article/details/136730026&#xff0c;可以先通过这篇文章对整体进行简单了解一下。 GT收发器介绍 参考xilinx手册ug476 对于7系列的FPGA&#xff0c;共有3个系列&#xf…

SQL Server 数据库常见提权总结

前面总结了linux和Windows的提权方式以及Mysql提权&#xff0c;这篇文章讲讲SQL Server数据库的提权。 目录 基础知识 权限判定 系统数据库 存储过程 常见系统存储过程 常见扩展存储过程 xp_cmdshell扩展存储过程提权 xp_dirtree写入文件提权 sp_oacreate提权 xp_re…

那些激励你深入研究技术的语录

遇到耗时高的问题&#xff0c;90%能用重启解决&#xff0c;但是不找到原因&#xff0c;问题一定会再次出现。 代码里的Bug就像房间里的老鼠&#xff0c;你不找到它&#xff0c;它就会一直捣乱。 代码的质量决定了程序的稳定性&#xff0c;而程序的稳定性则决定了业务的成败。 不…

面试题:Redis

一、为什么要用Redis&#xff1f; 1、内存数据库&#xff0c;快&#xff0c;很快....... 2、工作单线程worker&#xff0c;串行化、原子操作. &#xff08;IO线程是多线程&#xff09;- 避免上下文切换 3、IO模型&#xff08;epoll&#xff09;, 支撑高并发. 4、kv模型&…

风电机组的CMS(Condition Monitoring System,状态监测系统)收集的振动信号中包含的噪声主要来源

风电机组的CMS&#xff08;Condition Monitoring System&#xff0c;状态监测系统&#xff09;收集的振动信号中包含的噪声主要来源于风电机组在运行过程中的各种机械部件和环境因素。具体来说&#xff0c;这些噪声主要包括&#xff1a; 机械噪声及结构噪声&#xff1a; 齿轮箱…

华为防火墙配置指引超详细(包含安全配置部分)以USG6320为例

华为防火墙USG6320 华为防火墙USG6320是一款高性能、高可靠的下一代防火墙,适用于中小型企业、分支机构等场景。该防火墙支持多种安全功能,可以有效抵御网络攻击,保护网络安全。 目录 华为防火墙USG6320 1. 初始配置 2. 安全策略配置 3. 防火墙功能配置 4. 高可用性配…

Linux shell编程学习笔记42:md5sum

0 前言 前几天在国产电脑上遇到一个问题&#xff0c;先后接到两个文件&#xff0c;如何判断这两个文件内容是否相同&#xff1f; 如果是在Windows系统&#xff0c;可以用fc命令&#xff0c;或者用我自己写的FileInfo&#xff0c;提取两个文件有MD5、SHA1、CRC32值进行比较来判…

搭建文件服务器,按组别授权,并且可查看操作日志。

搭建一个文件服务器并实现按组别授权以及操作日志查看&#xff0c;可以使用开源的解决方案如Samba&#xff08;在Linux环境下&#xff09;或Windows Server中的DFS&#xff08;分布式文件系统&#xff09;结合Active Directory进行权限管理。以下是一个基于Samba和Linux环境的基…

(五)Nacos配置管理

1.Nacos配置管理 Nacos除了可以做注册中心&#xff0c;同样可以做配置管理来使用。 1.1.统一配置管理 当微服务部署的实例越来越多&#xff0c;达到数十、数百时&#xff0c;逐个修改微服务配置就会让人抓狂&#xff0c;而且很容易出错。我们需要一种统一配置管理方案&#…

Windows系统搭建Oracle结合内网穿透实现公网访问本地数据库

文章目录 前言1. 数据库搭建2. 内网穿透2.1 安装cpolar内网穿透2.2 创建隧道映射 3. 公网远程访问4. 配置固定TCP端口地址4.1 保留一个固定的公网TCP端口地址4.2 配置固定公网TCP端口地址4.3 测试使用固定TCP端口地址远程Oracle 前言 Oracle&#xff0c;是甲骨文公司的一款关系…

吴恩达机器学习:实践实验室-应用机器学习的建议(Advice for Applying )

在这个实验室中&#xff0c;您将探索评估和改进机器学习模型的技术。 文章目录 1 - Packages2-评估学习算法&#xff08;多项式回归&#xff09;2.1拆分数据集2.1.1图列、测试集 2.2模型评估的误差计算&#xff0c;线性回归2.3比较训练和测试数据的表现 3-偏差和方差3.1绘图列…

python各类数据容器总结

各种数据容器的对比 是否支持下标索引 支持&#xff1a;列表、元组、字符串-序列类型 不支持&#xff1a;集合、字典 是否支持重复元素 支持&#xff1a;列表、元组、字符串-序列类型 不支持&#xff1a;集合、字典-非序列类型 是否可以修改 支持&#xff1a;列表、集合、字…

【YOLOV5 入门】——环境配置(Miniconda/Pytorch/YOLOv5/PYPI镜像源)

声明&#xff1a;笔记是毕设时根据B站博主视频学习时自己编写&#xff0c;请勿随意转载&#xff01; 计划&#xff1a; 入门篇&#xff1a;环境安装、模型检测、构建自定义数据集、训练数据集、可视化界面搭建、Web系统搭建。拓展篇&#xff1a;使用服务器训练、使用pycharm和…

|行业洞察·趋势报告|《2024年时尚潮流趋势洞察-31页》

报告内容的详细解读&#xff1a; |趋势洞察库| 关注我 主页个人介绍 查看完整报告 1. 新中式潮流 定义与特点&#xff1a;新中式风格是将传统文化元素与现代审美相结合的一种风格&#xff0c;它在服装、美妆、美食和家居等多个领域都有广泛的应用。热度分析&#xff1a;新中…