Loading [MathJax]/jax/input/TeX/config.js
前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >移情别恋c++ ദ്ദി˶ー̀֊ー́ ) ——14.哈希(3)(布隆过滤器和位图)

移情别恋c++ ദ്ദി˶ー̀֊ー́ ) ——14.哈希(3)(布隆过滤器和位图)

作者头像
hope kc
发布于 2024-10-24 00:42:26
发布于 2024-10-24 00:42:26
14300
代码可运行
举报
文章被收录于专栏:学习学习
运行总次数:0
代码可运行
在 C++ 中,bitsetBloom Filter 是两种重要的数据结构,分别用于处理位操作和概率性数据存储。接下来,我们将详细探讨这两种结构的定义、实现、应用场景及其优缺点。
一、C++ 中的 bitset
1. 定义

bitset 是 C++ 标准库中的一个类模板,主要用于管理固定大小的位集合。它能够在一个单一的对象中存储多个二进制位,非常适合用于需要高效存储和快速访问位信息的场景。

2. 基本特性
  • 固定大小:创建 bitset 时需要指定大小,一旦定义,大小不能改变。
  • 位操作:支持与、或、异或等位操作。
  • 高效存储:每个位占用一个比特空间,内存使用效率高。
  • 访问便利:支持下标操作,可以直接通过索引访问某个位。
3. 使用示例
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
#include <iostream>
#include <bitset>

int main() {
    std::bitset<8> bset; // 创建一个大小为8的bitset

    bset.set(1); // 设置第1位为1
    bset.set(3); // 设置第3位为1
    std::cout << "Bitset: " << bset << std::endl; // 输出:00001010

    bset.flip(2); // 翻转第2位
    std::cout << "After flip: " << bset << std::endl; // 输出:00001110

    std::cout << "Size: " << bset.size() << std::endl; // 输出:8
    std::cout << "Count of set bits: " << bset.count() << std::endl; // 输出:3

    return 0;
}
4. 应用场景
  • 标记数据:适用于需要标记大量布尔值的场景,比如图的遍历。
  • 内存管理:用于管理大量的开关状态。
  • 算法优化:在某些算法中,如快速查找、去重等场景中,能够提高性能。
5. 优缺点

优点

  • 内存占用少,速度快。
  • 支持丰富的位操作,灵活性强。

缺点

  • 大小固定,无法动态调整。
  • 仅适用于较小规模的位操作。
6.模拟实现
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
#include<iostream>
#include<vector>
using namespace std;

namespace zone
{
	template<size_t n>
	class bitset
	{

		bitset()
		{
			bit.resize(N / 32 + 1, 0);//记得要加1;
		}
		void set(size_t x)
		{
			size_t i = x / 32;
			size_t j = x % 32;
			bit[i] |= 1 << j;//要求第j个比特位是1,其余位都是0
			//因为vs是小端存储,1是这样:(低)01 00 00 00(高),而左移并不是向左移动,而是向高位移动!!!!
		}

		void reset(size_t x)
		{
			size_t i = x / 32;
			size_t j = x % 32;
			bit[i] &= ~(1 << j);//要求第j个比特位是0,其余位都是1,与上文要求相反,可以直接取反
		}


		bool test(size_t x)
		{
			size_t i = x / 32;
			size_t j = x % 32;
			return bit[i] &(1<<j);//这里很巧妙,如果原位置上是0,那么返回就是false(0),如果不是0,则无论是多少,都返回true(非零)
		}

	private:
		vector<int> bit;
	};



}

二、Bloom Filter
1. 定义

Bloom Filter 是一种空间效率极高的概率性数据结构,主要用于检测某个元素是否在集合中。与 bitset 不同,Bloom Filter 允许出现一定的误判,即可能会错误地判断某个元素在集合中(假阳性),但绝不会漏掉真实存在的元素(假阴性)。

2. 基本特性
  • 哈希函数:Bloom Filter 使用多个哈希函数来映射元素到位数组。
  • 误判概率:通过适当的位数组大小和哈希函数数量,可以控制误判率。
  • 不可删除:一旦元素被添加到 Bloom Filter 中,无法删除。
3. 使用示例
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
#include <iostream>
#include <vector>
#include <functional>
#include <bitset>

class BloomFilter {
private:
    std::vector<bool> bits;
    size_t size;
    int hashCount;

    size_t hash1(const std::string& str) {
        std::hash<std::string> hash_fn;
        return hash_fn(str) % size;
    }

    size_t hash2(const std::string& str) {
        std::hash<std::string> hash_fn;
        return (hash_fn(str) / size) % size;
    }

public:
    BloomFilter(size_t n, int k) : size(n), hashCount(k) {
        bits.resize(n);
    }

    void add(const std::string& str) {
        for (int i = 0; i < hashCount; ++i) {
            bits[hash1(str)] = true;
            bits[hash2(str)] = true;
        }
    }

    bool contains(const std::string& str) {
        for (int i = 0; i < hashCount; ++i) {
            if (!bits[hash1(str)] || !bits[hash2(str)]) {
                return false; // 如果有一个哈希位置为0,说明一定不在
            }
        }
        return true; // 否则可能在
    }
};

int main() {
    BloomFilter bf(100, 2);
    bf.add("hello");
    bf.add("world");

    std::cout << "Contains 'hello': " << bf.contains("hello") << std::endl; // 输出:1
    std::cout << "Contains 'world': " << bf.contains("world") << std::endl; // 输出:1
    std::cout << "Contains 'test': " << bf.contains("test") << std::endl; // 输出:0(可能误判为1)

    return 0;
}
4. 应用场景
  • 数据库:在数据库中快速判断某个记录是否存在于索引中。
  • 网络:在网络应用中检查请求的 URL 是否在某个黑名单中。
  • 缓存系统:在大规模缓存中快速判断数据是否在缓存中,避免不必要的查找。
5. 优缺点

优点

  • 占用内存少,适合大规模数据。
  • 能够快速判断元素是否存在。

缺点

  • 可能产生误判。
  • 无法删除元素,更新数据时可能会导致误判率增加。
6.模拟实现
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
#include<iostream>
#include<string>
#include<bitset>
using namespace std;

namespace zone
{
	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;
		}
	};





	template<size_t N,class K=string,class hashfunc1= BKDRHash, class hashfunc2=APHash, class hashfunc3=DJBHash>
	class boomfilter
	{
		void Set(const K& key)
		{
			size_t hash1 = hashfunc1()(key) % N;//这里使用了临时变量生成了函数
			size_t hash2 = hashfunc2()(key) % N;
			size_t hash3 = hashfunc3()(key) % N;

			bs.set(hash1);
			bs.set(hash2);
			bs.set(hash3);
		}

		bool Test(const K& key)
		{
			//false一定是准确的
			size_t hash1 = hashfunc1()(key) % N;//这里使用了临时变量生成了临时函数
			size_t hash2 = hashfunc2()(key) % N;
			size_t hash3 = hashfunc3()(key) % N;

			if (bs.test(hash1) == false)
				return false;
			if (bs.test(hash2) == false)
				return false;
			if (bs.test(hash3) == false)
				return false;

			//true是有可能误判的
			return true;

		}



	   private:
		  bitset<N> bs;
	};
三、总结与比较
1. 相同点
  • 高效存储:两者都能够在内存使用上做到高效。
  • 位操作:都可以在位级别进行操作,适合处理布尔类型的数据。
2. 不同点
  • 用途bitset 主要用于存储和操作固定数量的布尔值,而 Bloom Filter 是一种概率性数据结构,主要用于检测元素是否存在于集合中。
  • 误判bitset 是准确的,而 Bloom Filter 则允许一定的误判。
  • 大小调整bitset 大小固定,而 Bloom Filter 可以根据需要动态调整。
3. 选择建议
  • 如果你的应用场景需要准确的布尔值存储和操作,且数据规模不大,使用 bitset 更加合适。
  • 如果你处理的是海量数据,且可以接受一定的误判,Bloom Filter 是一个更好的选择。
四、总结

bitsetBloom Filter 是 C++ 中处理位操作和概率性存储的强大工具。通过深入理解这两种数据结构的特性、应用及其优缺点,我们可以在实际开发中做出更好的选择。在现代应用中,掌握这些工具能极大提升程序的性能和内存利用率,是程序员必备的技能之一。

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2024-10-23,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
【C++修炼之路】25.哈希应用--布隆过滤器
我们在使用新闻客户端看新闻时,它会给我们不停地推荐新的内容,它每次推荐时要去重,去掉那些已经看过的内容。问题来了,新闻客户端推荐系统如何实现推送去重的? 用服务器记录了用户看过的所有历史记录,当推荐系统推荐新闻时会从每个用户的历史记录里进行筛选,过滤掉那些已经存在的记录。 如何快速查找呢?
每天都要进步呀
2023/03/28
8670
【C++修炼之路】25.哈希应用--布隆过滤器
位图/布隆过滤器/海量数据处理方式
所谓位图,就是用每一位来存放某种状态,适用于海量数据,数据无重复的场景。通常是用来判断某个数据存不存在的。
二肥是只大懒蓝猫
2023/03/30
3870
位图/布隆过滤器/海量数据处理方式
【C++】BloomFilter——布隆过滤器
位图的优点是节省空间,快,缺点是要求范围相对集中,如果范围分散,空间消耗上升,同时只能针对整型,字符串通过哈希转化成整型,再去映射,对于整型没有冲突,因为整型是有限的,映射唯一的位置,但是对于字符串来说,是无限的,会发生冲突,会发生误判:此时的情况的是不在是正确的,在是不正确的,因为可能不来是不在的,但是位置跟别人发生冲突,发生误判
平凡的人1
2023/10/15
4490
【C++】BloomFilter——布隆过滤器
【C++】哈希应用:位图 哈希切分 布隆过滤器
1. 大厂经典的面试题,给你40亿个不重复的无符号整数,让你快速判断一个数是否在这40亿个数中,最直接的思路就是遍历这40亿个整数,逐一进行比对,当然这种方式可以倒是可以,但是效率未免太低了。 另一种方式就是排序+二分的查找,因为二分查找的效率还是比较高的,logN的时间复杂度,但是磁盘上面无法进行排序,排序要支持下标的随机访问,这40亿个整数又无法加载到内存里面,你怎么进行排序呢?所以这样的方式也是不可行的。 那能不能用红黑树或者哈希表呢?红黑树查找的效率是logN,哈希表可以直接映射,查找的效率接近常数次,虽然他们查找的效率确实很快,但是40亿个整数,那就是160亿字节,10亿字节是1GB,16GB字节红黑树和哈希表怎么能存的下呢?这还没有算红黑树的三叉链结构,每个结点有三个指针,而且哈希表每个结点会有一个next指针,算上这些的话需要的内存会更大,所以用红黑树或哈希表也是无法解决问题的。
举杯邀明月
2023/04/12
6230
【C++】哈希应用:位图 哈希切分 布隆过滤器
哈希的应用——布隆过滤器
那有没有什么 办法可以解决呢? 这就是我们今天要学的布隆过滤器(Bloom Filter)
YIN_尹
2024/01/23
2580
哈希的应用——布隆过滤器
【C++航海王:追寻罗杰的编程之路】哈希的应用——位图 | 布隆过滤器
位图的概念:所谓位图,就是用每一位来存放某种状态,适用于海量数据,数据无重复的场景。通常是用来判断某个数据是否存在的。
枫叶丹
2024/07/15
1250
【C++航海王:追寻罗杰的编程之路】哈希的应用——位图 | 布隆过滤器
【C++高阶】哈希之美:探索位图与布隆过滤器的应用之旅
前言:在数据科学的浩瀚星空中,哈希函数犹如一颗璀璨的星辰,以其独特的光芒照亮了数据处理的每一个角落。哈希,这一简单而强大的技术,通过将任意长度的输入(如字符串、数字等)映射到固定长度的输出(即哈希值),实现了数据的快速定位与索引。然而,哈希的魅力远不止于此,当它与位图和布隆过滤器相结合时,更是催生出了一系列高效且实用的数据处理方案
Eternity._
2024/08/05
1060
【C++高阶】哈希之美:探索位图与布隆过滤器的应用之旅
【C++】位图应用 | 布隆过滤器
给40亿个不重复的无符号整数,没排过序,给一个无符号整数,如何快速判断一个数是否在这40亿个数中
lovevivi
2023/10/17
2010
【C++】位图应用 | 布隆过滤器
【C++高阶】哈希—— 位图 | 布隆过滤器 | 哈希切分
之前我们已经在这篇文章中 【C++高阶】哈希函数底层原理全面探索和深度解析-CSDN博客
IsLand1314
2024/10/15
1580
【C++高阶】哈希—— 位图 | 布隆过滤器 | 哈希切分
C++:位图和布隆过滤器
问题:给40亿个不重复的无符号整数,没排过序。给一个无符号整数,如何快速判断一个数是否在 这40亿个数中。【腾讯】
小陈在拼命
2024/05/10
1160
C++:位图和布隆过滤器
C++哈希应用-位图/布隆过滤器/海量数据处理
C++位图/布隆过滤器/海量数据处理 零、前言 一、位图 1、位图概念 2、位图接口的介绍以及实现 3、位图的应用 二、布隆过滤器 1、布隆过滤器概念和介绍 2、布隆过滤器的操作及实现 3、布隆过滤器的分析 三、海量数据处理 零、前言 本章主要讲解C++中对哈希的应用有关方面的内容,位图,布隆,海量数据处理 一、位图 1、位图概念 位图概念: 位图其实就是哈希的变形,同样通过映射来处理数据,只不过位图本身并不存储数据,而是存储标记 通过一个比特位来标记这个数据是否存在,1代表存在,0代表不
用户9645905
2022/11/30
5380
C++哈希应用-位图/布隆过滤器/海量数据处理
C++ 哈希的应用【布隆过滤器】
注册账号是进行网络冲浪的第一步操作,而拥有一个具有个性且独一无二的用户昵称是非常重要的,很多人在填写昵称时,常常会看到 此昵称已存在 的提示,系统是如何快速知道当前昵称是否存在呢?总不能挨个去遍历对比吧,这时候就需要我们本文中的主角: 布隆过滤器
北 海
2023/08/02
2700
C++ 哈希的应用【布隆过滤器】
【C++】STL --- 哈希
在 C++98 中,STL 提供了底层为红黑树结构的一系列关联式容器,在查询时效率可达到 O(logN),即最差情况下需要比较红黑树的高度次,当树中的节点非常多时,查询效率也不理想。最好的查询是,进行很少的比较次数就能够将元素找到,因此在 C++11 中,STL 又提供了4个 unordered 系列的关联式容器,这四个容器与红黑树结构的关联式容器使用方式基本类似,只是其底层结构不同,本文中只对 unordered_map 和 unordered_set 进行介绍,unordered_multimap 和 unordered_multiset 大家可以查看文档介绍 - - - unordered_multimap / unordered_multiset.
YoungMLet
2024/03/01
1840
【C++】STL --- 哈希
【C++进阶】位图/布隆过滤器与海量数据处理
我们知道数据的最小存储位是比特(bite),每个比特位只能是0或1,我们用1和0来表示在或不在,或是其它类型的状态信息,这种结构称作位图。
aosei
2024/01/23
1570
【C++进阶】位图/布隆过滤器与海量数据处理
位图与布隆过滤器
此篇文章针对大量数据进行筛选或者判断重复,存在等一系列侧重于在特定空间,时间等允许范围内进行选择的问题提出解决方案。
羑悻的小杀马特.
2025/01/23
910
位图与布隆过滤器
【C++】哈希(位图,布隆过滤器)
给 40亿个不重复的无符号整数, 没排过序。给一个无符号整数,如何快速判断一个数是否在
The sky
2023/04/12
3160
【C++】哈希(位图,布隆过滤器)
【C++从小白到大牛】布隆过滤器
上一篇文章我们已经学习了位图的应用,但是位图一般只能处理整形,如果内容编号是字符串,就无法处理了。而我们又知道如果只用哈希表存储用户记录,缺点就是浪费空间。但是我们将哈希表和位图结合起来呢,就是我们的布隆过滤器!
用户11316056
2024/10/16
1010
【C++从小白到大牛】布隆过滤器
C++哈希应用——布隆过滤器
用哈希表存储用户记录,缺点是需要消耗较大的内存;用位图存储用户记录,缺点是位图一般处理整形,内容是字符串或者自定义类型就很勉强。基于以上,若将哈希和位图结合,称为布隆过滤器,会不会把上面的问题都解决了呢?
梨_萍
2023/04/25
4880
C++哈希应用——布隆过滤器
极致高效的数据处理:位图、布隆过滤器与哈希切分的奇妙之旅
本文将带领你深入探索哈希的三大高效应用——位图、布隆过滤器和哈希切分。它们如同精巧的齿轮,共同驱动着现代计算系统的高效运作。从减少存储空间到加速查找效率,从数据去重到流式处理,这些技术在幕后悄然发挥着巨大的力量。让我们一起揭开哈希算法的神秘面纱,领略数据处理的艺术之美。
suye
2024/11/19
1630
极致高效的数据处理:位图、布隆过滤器与哈希切分的奇妙之旅
【c++】哈希>unordered容器&&哈希表&&哈希桶&&哈希的应用详解
在C++98中,STL提供了底层为红黑树结构的一系列关联式容器,在查询时效率可达到log_2N,即最差情况下需要比较红黑树的高度次,当树中的节点非常多时,查询效率也不理想。最好的查询是,进行很少的比较次数就能够将元素找到,因此在C++11中,STL又提供了4个unordered系列的关联式容器,这四个容器与红黑树结构的关联式容器使用方式基本类似,只是其底层结构不同,本文中只对unordered_map和unordered_set进行介绍,unordered_multimap和unordered_multiset可查看文档介绍
用户10925563
2024/06/10
3150
【c++】哈希>unordered容器&&哈希表&&哈希桶&&哈希的应用详解
相关推荐
【C++修炼之路】25.哈希应用--布隆过滤器
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
本文部分代码块支持一键运行,欢迎体验
本文部分代码块支持一键运行,欢迎体验