编写 C++ 程序实现 Bloom 过滤器数据结构17 Mar 2025 | 5 分钟阅读 引言布隆过滤器是一种概率性数据结构,它提供了空间高效的方式来判断一个元素是否属于一个集合。自1970年Burton Howard Bloom开发以来,它们已广泛应用于许多计算机科学和工程领域。在网络路由器、数据库和分布式系统等内存或存储限制至关重要的场景中,布隆过滤器极其有用。 ![]() 从根本上讲,布隆过滤器利用一个位集合和一组哈希函数。当一个元素被添加到过滤过程中时,它会经过多个哈希函数,生成位数组中的一组索引。然后,通过将这些索引设置为1,表示该元素包含在过滤器中。另一方面,当查询一个元素是否存在时,过滤器会哈希该元素并验证位数组中匹配的索引。如果所有这些索引都设置为1,则该元素可能存在于集合中。然而,哈希冲突可能导致误报。 布隆过滤器的空间效率是其主要优点之一。布隆过滤器只保留集合成员数据的浓缩版本,而不是像哈希表或树等传统数据结构那样存储组件本身。这使得它们非常适合缓存、拼写检查和重复检测等内存使用需要严格控制的应用。 尽管布隆过滤器很有效,但也存在权衡。由于布隆过滤器是概率性的,可能会出现误报,但可以通过改变哈希函数的数量和位数组的大小来控制其可能性。此外,添加到过滤器的项目不能在不影响其余组件的情况下删除。因此,布隆过滤器适用于集合不可变或可以接受少量误报的场景。 总之,当内存或存储受限时,布隆过滤器为集合成员资格检查提供了一种强大而紧凑的解决方案。布隆过滤器使用紧凑的位数组表示和哈希算法,以受控的不准确结果概率提供快速的成员资格查询。 示例让我们举一个例子来说明C++中的布隆过滤器。 输出 Is 'hello' in filter: 1 Is 'world' in filter: 1 Is 'example' in filter: 1 Is 'foo' in filter: 0 Is 'bar' in filter: 0 说明 在此示例中,在BloomFilter类的上下文中,集合由一个名为bitArray的std::bitset表示。由于其原始大小为1000,因此它可以表示1000个不同的项目。 为了将项目映射到位数组中的索引,使用了三个不同的哈希函数:hashFunction1、hashFunction2和hashFunction3。 当一个元素添加到布隆过滤器(使用add方法)时,哈希函数确定的索引处的相关位被设置为1。 includes方法确定给定某个元素,哈希函数确定的每个索引处的每个位被设置为1的程度。在这种情况下,函数返回true,表明该元素很可能已添加到集合中(尽管可能存在误报)。 元素“hello”、“world”和“example”被添加到给定main函数中的过滤器中。之后,它会验证这些项目以及两个被忽略的元素(“foo”和“bar”)是否存在。 布隆过滤器在main函数中创建,并通过add方法向其中添加了几个组件(“hello”、“world”和“example”)。除了未明确引入的元素(“foo”和“bar”)之外,还使用contains函数检查这些元素的存在性。考虑到未添加到过滤器的元素可能出现误报,结果指示每个搜索到的元素是否可能存在于过滤器中。 结论布隆过滤器的实现:可执行文件构造了一个名为BloomFilter的类,该类具有布隆过滤器的所有功能。过滤器的位数组可以用std::bitset表示,并且使用三个哈希函数(std::hashstd::string)将项目映射到位数组索引。 添加和包含操作:BloomFilter类提供了将项目添加到现有过滤器(add)以及确定元素是否存在于过滤器中(contains)所需的技术。当添加元素时,哈希函数用于将位数组中的相关位设置为1。includes方法通过确定所有必要的位是否都已设置来确定给定元素是否可能属于指定集合。 概率性质:布隆过滤器有可能产生误报,但提供了一种空间高效的成员资格测试方法。当元素被过滤器错误地显示为存在于集合中而实际上可能不存在时,这称为误报。通过改变位数组的大小和使用的哈希函数数量,可以管理不准确结果的可能性。 使用示例:通过将项目(“hello”、“world”和“example”)放入过滤器然后验证它们的存在,main函数演示了使用布隆过滤器的最佳方式。此外,它还会查找未考虑的项目(“bar”和“foo”),突出显示出现误报的可能性。 可伸缩性和优化:根据预期的项目数量和预期的误报率,可以更改位数组的宽度(此版本中为1000)和使用的哈希算法数量。通过哈希冲突最小化和适当的加密函数选择等优化,可以提高布隆过滤器的准确性和速度。 最后,该软件附带的C++程序提供了布隆过滤器数据结构的基本实现,展示了其在有效成员资格测试方面的有用性,该测试表现出受控的概率行为。 下一主题C++中的Xor_eq |
C++ 是一种类似的编程语言,它结合了 C 编程语言和 Simula67 的特性(Simula67 被认为是第一门面向对象的语言)。C++ 建立了类和对象的概念。您是否正在寻找一本入门好书...
阅读 6 分钟
? 本文将讨论在 C++ 中将无穷大分配给数字的几种方法。在进行实现之前,我们必须了解无穷大。什么是无穷大和负无穷大?无穷大是正整数通过稀释产生的值...
阅读 4 分钟
在本文中,您将讨论 C++ 中的内置函数及其各种函数和示例。在讨论内置函数之前,您必须了解 C++ 中的函数。函数是代码的一部分,只有在被调用时才会执行。参数是指...
阅读9分钟
在组合数学和计算机科学中,稳定婚姻问题是一个著名的谜题。它涉及在两组元素(例如男性和女性)之间建立稳定匹配,其中每个人对构成另一组的个体都有不同的偏好。如果...
阅读 4 分钟
这个 C++ 应用程序使用一次性密码加密技术来加密任何消息。输入不区分大小写,并兼容所有字符。在解密的消息中,空格会生成为随机字符,而不是被忽略。例如:用于实现一次性密码的 C++ 程序源代码...
阅读 3 分钟
C++ 中的 Vector 是什么?在 C++ 中,vector 是一个序列容器,它在连续的内存块中存储相同类型的元素。Vector 中的每个元素都分配有一个数字索引,用于访问该元素。Vector 类似...
阅读 4 分钟
布尔值是 C++ 中的一种数据类型,表示真或假值。它通常在编程中用于控制程序流、做出决策和评估条件。在 C++ 中,布尔值是一种可以具有两个可能值的数据类型:true 或 false。布尔值是...
5 分钟阅读
Kruskal 算法简介:在快速发展的科技和信息世界中,算法对于解决复杂问题至关重要。Kruskal 算法是一种简单且效果良好的出色算法。它源于图论,非常适合寻找连接……
11 分钟阅读
按照特定顺序访问二叉树边界节点的过程称为边界遍历。左边界(不包含左叶节点)、叶节点以及右边界(不包含右叶节点)……
阅读 6 分钟
在本文中,我们将讨论 C++ 和 JavaScript 之间的区别。但在讨论区别之前,我们必须了解 C++ 和 JavaScript 的优缺点。简介:C++:C++,或 CPP,是一种通用、静态类型、面向对象的编程语言。在 AT&T(美国)的贝尔实验室...
5 分钟阅读
我们请求您订阅我们的新闻通讯以获取最新更新。
我们提供所有技术(如 Java 教程、Android、Java 框架)的教程和面试问题
G-13, 2nd Floor, Sec-3, Noida, UP, 201301, India