位图,布隆过滤器的原理和实现

位图&布隆过滤器的原理及实现 首先介绍位图实现的前置知识位运算,再介绍位图的实现(插入,查找,删除),通过位图来实现布隆过滤器,最后描述其优缺点和使用场景最后写出布隆过滤器和位图的区别。 阅读详情

位图

所谓位图,就是用每一位来存放某种状态,适用于海量数据,数据无重复的场景,通常是用来判断某个数据是否存在
比方说现在有40亿个未排序的无符号整数,请问如何判断一个数是否存在于这40亿个数中?
这个问题就很适合用位图来解决,题目中说这些数据都是无符号整数而无符号整数最大能取到0xffffffff(约43亿),并且题目只要求我们判断该数据是否存在,因此我们只需要用一个比特位来标识该数值是否存在即可
在这里插入图片描述
如上图,插入了1, 3, 7三个数据,我们只要把第1, 3, 7个比特位赋值1即可。

namespace ssj
{
	template<size_t N>
	class bitset
	{
	public:
		bitset()
		{
			// 初始化,因为/向下取整,因此我们分配一个字节即可
			_bits.resize(N / 8 + 1, 0);
		}
		void set(size_t x) // 标记该数存在
		{
			size_t i = x / 8;
			size_t j = x % 8;
			_bits[i] |= (1 << j);
		}
		void reset(size_t x)
		{
			size_t i = x / 8;
			size_t j = x % 8;
			_bits[i] &= (~(1 << j));
		}
		bool test(size_t x) // 检查该数是否存在
		{
			size_t t = x / 8;
			size_t j = x % 8;
			return _bits[i] & (1 << j);
		}

	private:
		std::vector<char> _bits;
	};
}

template<size_t N>
class TwoBitSet
{
public:
	void Set(size_t x)
	{
		if (!bs1.test(x) && !_bs2.test(x))
		{
			_bs2.set(x);
		}
		else if (!_bs1.test(x) && _bs2.test(x))
		{
			_bs1.set(x);
			_bs2.reset(x);
			// 10 表示已经出现2次或以上,不用处理
		}
	}
	void PrintOnceNum()
	{
		for (size_t i = 0; i < N; ++i)
		{
			if (!_bs1.teset(i) && _bs2.test(i))
			{
				cout << i << endl;
			}
		}
	}

private:
	ssj::bitset<N> _bs1;
	ssj::bitset<N> _bs2;
};

布隆过滤器

位图固然是一种非常优秀的结构,他不仅节省空间而且效率高,但他也有一个很大的局限性——只能处理整数。对字符串和自定义类型对象位图没办法处理。原因很直观,对整型来讲,不管是长整型还是无符号整型数据,他们的数量终究是有限并且可以很简单的和某个位置一一对应,但是字符串的非常数量非常多,其中字符的增多和减少,或者位置的互换都会形成新的字符串,因此在有限的比特位中若我们想给每个字符串都提供一个比特位,那么必然会造成位置冲突的局面。现在要介绍的布隆过滤器可以比较有效的解决这个问题。

概念

布隆过滤器是由布隆(Burton Howard Bloom)在1970年提出的一种紧凑型的,比较巧妙的概率型数据结构,特点是高效地插入和查询,可以用来告诉你“某样东西一定不存在或可能存在”,它是用多个哈希函数,将一个数据映射到 位图结构中,此种方式不仅可以提升查询效率,也可以节省大量的内存空间。

代码

#include <bitset>
#include <string>
#include <time.h>

using namespace std;

/*下面三个都是哈希函数,可以自行选择合
适的哈希函数,数量最好控制在3-5个*/
struct BKDRHash
{
	size_t operator()(const string& s)
	{
		// BKDR
		size_t value = 0;
		for (auto ch : s)
		{
			value *= 31;
			value += ch;
		}
		return value;
	}
};

struct APHash
{
	size_t operator()(const string& s)
	{
		size_t hash = 0;
		for (long 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 DJBHash
{
	size_t operator()(const string& s)
	{
		size_t hash = 5381;
		for (auto ch : s)
		{
			hash += (hash << 5) + ch;
		}
		return hash;
	}
};
// X代表我们所给的比特位是数据量的几倍
template <size_t N,
	size_t X = 8,
	class K = string,
	class HashFunc1 = BKDRHash,
	class HashFunc2 = APHash,
	class HashFunc3 = DJBHash>
class BloomFilter
{
public:
	void Set(const K& key)
	{
		size_t len = X * N;
		size_t index1 = HashFunc1()(key) % len;
		size_t index2 = HashFunc2()(key) % len;
		size_t index3 = HashFunc3()(key) % len;

		_bs.set(index1);
		_bs.set(index2);
		_bs.set(index3);
	}
	// 检查该数据是否存在
	bool Test(const K& key)
	{
		size_t len = X * N;
		size_t index1 = HashFunc1()(key) % len;
		if (_bs.test(index1) == false) return false;

		size_t index2 = HashFunc2()(key) % len;
		if (_bs.test(index2) == false) return false;

		size_t index3 = HashFunc3()(key) % len;
		if (_bs.test1(index3) == false) return false;

		return true;
	}

private:
	bitset<X* N> _bs;
};

删除

布隆过滤器不能直接支持删除工作,因为在删除一个元素时,可能会影响其他元素。
一种删除方法:将布隆过滤器中的每个比特位扩展成一个小的计数器,插入元素时给计数器加一,删除时减一,通过多占用几倍存储空间的代价来增加删除操作。

布隆过滤器的优点

  1. 增加和查询元素的时间复杂度为O(K),(K为哈希函数的个数,一般比较小),与数据量大小无关
  2. 哈希函数相互之间没有关系,方便硬件并行运算
  3. 布隆过滤器不需要存储元素本身,在某些对保密要求比较严格的场合有很大优势
  4. 在能够承受一定的误判时,布隆过滤器比其他数据结构有很大的空间优势
  5. 数据量很大时,布隆过滤器可以表示全集,其他数据结构不能
  6. 使用同一组散列函数的布隆过滤器可以进行交、并、差运算

布隆过滤器的缺点

  1. 有误判率,即存在假阳性(False Position),即不能准确判断元素是否在集合中(补救方法:再建立一个白名单,存储可能会误判的数据)
  2. 不能获取元素本身
  3. 一般情况下不能从布隆过滤器中删除元素
  4. 如果采用计数方式删除,可能会存在回绕问题
OSGEarth三维可视化避坑指南:如何高效加载SHP/TIF地理数据? 本文详细介绍了OSGEarth在三维地球可视化中高效加载SHP/TIF地理数据的实战策略,包括空间参考系配置、性能优化、二三维联动等关键技巧。通过具体案例和代码示例,帮助开发者解决坐标偏移、性能卡顿等常见问题,提升三维GIS开发效率。 阅读详情

相关推荐

【win11+vs 2017+OpenCV4.5.5+Qt5.12配置】详细安装过程+小问题解决

由于Qt5无法与最新的vs2022兼容,扩展工具中一直显示不可用,所以将vs降级成vs2017。在安装Qt的过程中,会选择安装Qt套件,其中就的MCVS 2017,说明vs2017是与qt兼容的。当然也可以用qt creator这一原生IDE。OpenCV版本目前是最新的4.8.0,使用过程中没有什么问题,但是还是安装低版本大概率避免一些玄学问题。

qq_45306739的博客 3350

【高阶数据结构】位图&布隆过滤器

处理海量数据的数据结构——位图&布隆过滤器

不能再留遗憾了的博客 1596

大语言模型在建筑规范自动化合规审查中的微调策略与规模效应实践

大语言模型(LLM)通过在海量文本数据上预训练,具备了强大的语言理解和生成能力。其核心原理是基于Transformer架构,通过自注意力机制捕捉长距离依赖关系。在工程实践中,为了将这种通用能力适配到建筑、法律、金融等高度专业化的垂直领域,通常需要采用领域微调技术。微调通过使用特定领域的高质量指令数据对模型参数进行更新,使其掌握专业术语、逻辑规则和任务范式,从而解决通用模型在专业场景下知识匮乏和“幻觉”问题。结合检索增强生成(RAG)技术,将动态外部知识库作为模型的“参考手册”,能进一步提升事实准确性并降低幻

weixin_30667831的博客 362

位图和布隆过滤器

哈希的应用!

学代码的咸鱼的博客 467

基于STM32与MPU6050的实时姿态检测系统设计与实现(源码+硬件解析)

本文详细介绍了基于STM32单片机与MPU6050传感器的实时姿态检测系统设计与实现。通过硬件解析、传感器校准、卡尔曼滤波算法和欧拉角计算,实现高精度姿态检测。提供完整源码和调试技巧,适用于无人机、平衡车等嵌入式开发项目,解决噪声干扰和数据漂移等常见问题。

jupi8的博客 494

2025.06.17【WGS】|多样品VCF文件中每个样品SNP数统计方法详解(含代码与注释)

摘要:本文介绍了一种从合并后的VCF文件中统计每个样品SNP数目的方法。通过解析VCF文件中的GT字段,排除纯合参考(0/0)和缺失(./.)的基因型,准确计算各样本的SNP位点数。文中提供了完整的Python脚本,利用bcftools工具高效处理大规模VCF文件,并支持输出SNP统计结果。该方法适用于群体遗传学和RAD-seq等高通量测序数据分析的质控环节,还可扩展为统计杂合/纯合SNP等进阶需求。脚本使用简单,只需输入VCF文件即可生成样本-SNP数目的统计报表。

1698

C++修炼:位图和布隆过滤器

详细讲解并模拟实现位图和布隆过滤器

但凡的博客 1519

AI开发提效10倍:从需求到部署的全流程实战指南(附Prompt模板)

用AI开发不是“偷懒”,而是把时间花在更有价值的地方——原来花80%时间写重复代码,现在用AI搞定后,能把精力放在“优化用户体验”“提升系统性能”这些核心工作上,这才是AI给开发者的真正红利。如果你还没开始用AI做开发,建议从“写一个简单接口”“补一段注释”开始尝试,先用起来再优化方法。记住:AI是工具,不是对手,学会驾驭它,你会发现开发效率提升的同时,还能告别无效加班。

这里只有干货:从 Modbus 通信到 MES 对接,从 YOLO 训练到工控机部署,带你搞定工业软件开发全流程。 1531

【干货】位图的实现与布隆过滤器

位图是用一个btye位来表示一个数据是否存在,再通过哈希函数确定一个数据所在的位置,这样处理会使当仅需要判断一个数据在不在的时候大大的提高效率,缩小内存的使用,如一个数据为int型,而一个int型的数据构成的位图能表示32个数据的存在状态。代码实现如下:Bitmap.h:#include<vector> classBitMap { public: Bi...

weixin_34337265的博客 134

QT实现Word读写

在windows环境下,我们可以通过ActiveQt实现Office自动化,相当于VB的VBA功能。 以下是一个实例: #include #include #include int main(int argc, char *argv[]) {     QApplication a(argc, argv);     //显示的打开一个word应用程序     QAxW

nameofhsw的专栏 1万+

告别License烦恼:手把手教你用VS Code+Cppcheck搭建免费的MISRA-C代码检查环境

本文详细介绍了如何使用VS Code和开源工具Cppcheck搭建免费的MISRA-C代码检查环境,帮助开发者规避商业工具的高额License费用。通过四步环境搭建和实战技巧,实现高效的代码静态检查,提升嵌入式开发的安全性和可靠性。

weixin_42523326的博客 248

布隆过滤器(Bloom Filter)

为什么 就当前互联网环境来说,头部的互联网生态越来越往高并发、分布式的形态发展。举例来说,各大网页的黑名单系统,爬虫的重复率判断。这些场景越来越多。 举例来说,实时状态下可能会对超过百亿级别的 URL 需要进行判断是否符合规范或者存在于系统中,能否正常使用。 通常情况下,每个 URL 的大小为 64B(字节),那么就按照100亿的 URL 数量来看,大概需要640GB的内存容量【】,对于当前线上服务器来说,… 这个值依然还是很大的!但如果利用布隆过滤器的优势,在没有失误率的情况下只需要100亿个比特,即

weixin_44744941的博客 3101

小白也能懂!一步步教你用FPGA加速YOLO目标检测(入门篇)

安装到 PYNQ 开发板中。该库为 PYNQ 平台提供了对量化神经网络(如 YOLO)的硬件加速支持。确保你的电脑已连接到外网,如 WiFi 或热点(手机热点理论上也可用,未实测)。当你看到安装成功的提示后,打开 Jupyter Notebook,你会发现在。趁这个机会,泡了杯茶,刷了会儿手机,顺便感慨了一下开源社区的强大……页面中多出了一些新的项目文件夹 —— 这就是我们刚才安装的。参数,浅拷贝只克隆最近一次提交,减少数据量,避免超时问题。初始化,打开该文件,即可运行我们的Tiny YOLO。

FJN110的博客 1597

位图与布隆过滤器 —— 海量数据处理

详细介绍了位图与布隆过滤器 —— 海量数据处理的方式方法

You build it, you run it 2490

怀旧版电脑GBC模拟器

再现原版GBC掌机的界面,电脑运行连游戏界面都一样大小,很怀旧,很真实,(英文版)强烈推荐,很小的文件,很难才找到的。

OV9734 DATASHEET,完整规格书

OV9734完整规格书,包括电气参数,尺寸规格,寄存器配置表等

位图与布隆过滤器:原理、差异与应用

在这篇文章中,你会学习到关于哈希思想的最常见的两个应用,也就是 位图 与 布隆过滤器,文章会讲解位图和布隆过滤器的概念,底层实现,对应的适应的场景,以及相关经典 海量数据面试题 及解析。

2301_77509762的博客 3465

复分析 阿尔福斯(Ahlfors) 第三版答案 英文

答案分为十章,有部分习题没有答案,全英文复分析阿尔福斯(Ahlfors) 第三版答案

【C++】位图与布隆过滤器(内含相关高频面试题)

本篇文章会对位图和布隆过滤器进行详解。同时还会给出位图和布隆过滤器相关的高频面试题与解答。希望本篇文章会对你有所帮助。位图和布隆过滤器是在计算机科学中常用的数据结构,它们分别具有不同的优点和缺点。空间效率高:位图使用的是位运算,在表示大量数据时,相比于传统的数组或哈希表等数据结构,可以极大地减少所需的存储空间。

weixin_67596609的博客 1610

温度PID控制PLC程序

温度PID稳定控制程序,适用于欧姆龙PLC,对其他PLC也具有很大参考价值

数据结构 - 位图 | 布隆过滤器 | 海量数据处理

数据结构 - 位图 | 布隆过滤器

2302_79539362的博客 1640

位图&&布隆过滤器

位图 位图其实也就是哈希的思想,就是用每一位来存放某种状态,通常是用来判断某个数据存不存在的。数据是否在给定的整形数据中,结果是在或者不在,刚好是两种状态,那么可以使用一个二进制比 特位来代表数据是否存在的信息,如果二进制比特位为1,代表存在,为0代表不存在。 位图的模拟实现 class BitSet { public: BitSet(const size_t& bitCount) :_bitCount(bitCount) { _bit.resize((bitCount >>

Adenson的博客 412

位图与布隆过滤器

位图与布隆过滤器

m0_74380143的博客 1057

C++——位图与布隆过滤器

先看一个面试题:给40亿个不重复的未排序的无符号整数,然后如何快速判断一个数是否在这40亿个数中以我们前面的知识,最先想到的有两种方法:1,排序+二分查找 2,存到哈希表和红黑树中再查但是题目中给的是40亿个整数,我们先算下需要的内存:1G就是1024MB,是1024*1024KB,是1024*1024*1024Byte,相当于10亿Byte,所以,40亿个数需要4*40Byte大概就是16G的空间,所以由于空间的限制,上面两种方法就都可以去掉了。

aaqq800520的博客 1221

哈希的应用:位图和布隆过滤器

位图 首先我们来看一道腾讯的面试题: 给40亿个不重复的无符号整数,没排过序。给一个无符号整数,如何快速判断一个数是否在这40亿个数中。 那么你会想到哪些解决方法呢? 遍历,时间复杂度 O(N) 排序 O(N * logN),利用二分查找 O(logN) 上面两种方法真的可以解决吗?40亿个不重复的无符号整数在内存中占多大空间呢? 232大概是42亿,4G空间大小,一个整数占4个字节,那就是16G的空间大小,实际上我们电脑的内存没有这么大。 那是否可以采用哈希进行映射处理呢? 可以开232个空间,对所有

是胖胖没错了的博客 320

数据结构之位图与布隆过滤器

数据结构之位图与布隆过滤器

Tlzns的博客 1053

【C++】哈希与布隆过滤器

【C++】位图与布隆过滤器

VHhhbb的博客 1404

C++哈希hash:位图、布隆过滤器的实现及应用

详细介绍了位图的原理及实现方式,具象化了哈希思想在具体场景中的使用方式及用途,深度解析了布隆过滤器的原理结构及实现方式。并分析其优缺点。

2201_75880188的博客 1255

C++哈希应用-位图/布隆过滤器/海量数据处理

C++位图/布隆过滤器/海量数据处理零、前言一、位图1、位图概念2、位图接口的介绍以及实现3、位图的应用二、布隆过滤器1、布隆过滤器概念和介绍2、布隆过滤器的操作及实现3、布隆过滤器的分析三、海量数据处理 零、前言 本章主要讲解C++中对哈希的应用有关方面的内容,位图,布隆,海量数据处理 一、位图 1、位图概念 位图概念: 位图其实就是哈希的变形,同样通过映射来处理数据,只不过位图本身并不存储数据,而是存储标记 通过一个比特位来标记这个数据是否存在,1代表存在,0代表不存在 位图通常情

~ 1486
上一篇: Linux多线程篇【5】——线程池
下一篇: 网络基础——HTTP协议及HTTPS
JayceSun449
博客等级 码龄5年 554粉丝 49原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

JayceSun449

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值