【C++学习】哈希的应用—位图与布隆过滤器

2024-06-13 1226阅读

目录

  • 1.位图
    • 1.1位图的概念
    • 1.2位图的实现
    • 3.位图的应用
    • 2.布隆过滤器
      • 2.1 布隆过滤器提出
      • 2.2布隆过滤器概念
      • 2.3如何选择哈希函数个数和布隆过滤器长度
      • 2.4布隆过滤器的实现
        • 2.4.1布隆过滤器插入操作
        • 2.4.2布隆过滤器查找操作
        • 2.4.3 布隆过滤器删除
        • 2.5 布隆过滤器优点
        • 2.6布隆过滤器缺陷
        • 3.海量数据面试题
          • 3.1 哈希切割
          • 3.2 位图应用
          • 3.3 布隆过滤器

            文章简介

            在这篇文章中,你会学习到关于哈希思想的最常见的两个应用,也就是 位图布隆过滤器

            文章会讲解位图和布隆过滤器的概念,底层实现,对应的适应的场景,以及相关经典 海量数据面试题 及解析。

            1.位图

            1.1位图的概念

            所谓位图,就是用每一位来存放某种状态,适用于海量数据,数据无重复的场景。通常是用来判断某个数据存不存在的。

            比如这道 腾讯 的面试题目:

            面试题目:给40亿个不重复的无符号整数,没排过序。给一个无符号整数,如何快速判断一个数是否在这40亿个数中。

            解析:

            40亿个整型数据所需内存大小:10亿字节约等于1G,那么40亿个整型,就是40亿*4(字节)=160亿字节≈16G。

            1. 遍历,时间复杂度O(N)
            2. 排序(O(NlogN)),利用二分查找: logN

            上面的两种做法都是不可行的,因为内存不够。

            1. 位图解决 数据是否在给定的整形数据中,结果是在或者不在,刚好是两种状态,那么可以使用一个二进制比特位(0/1)来代表数据是否存在的信息,如果二进制比特位为1,代表存在,为0代表不存在。

            第三种方法,利用位图解决,因为是要在40亿个数中查找,数据的类型是一个整型,范围为0~UINT_MAX。所以我们只需要UINT_MAX个比特位,所需的内存也就是512M,然后将这40亿个整数利用这UINT_MAX个比特位就可以表示他们的存在状态;

            图解:

            假设有一个整型数组array(如下图),因为里面的数据范围为1~22,所以我们就可以开一个int大小的数组(有32个比特位,可以表示32个不同数的存在状态),映射地址的方法这里采用的是直接定址法;

            计算:第i个整型中:i = (该数)/ 32;

            该整形中第j个比特位:j = (该数)% 32;

            【C++学习】哈希的应用—位图与布隆过滤器

            1.2位图的实现

            1. 因为位图需要整型的连续的空间,所以这里我们用vactor 即可

            2. 所开空间的大小的计算:

              这里开的是一个范围,假如上面的面试题,有40亿个整型数据,因为有40亿个数据,但是不能 只开40亿个比特位的空间,因为如果只开了40亿个比特位的话,就只能表示数据大小为0~40亿的数据,然而数据类型为int,数据最大值超过了40亿,这样超过了40亿的数据就表示不了了。

            3. 因为空间开的大小不一样,所以这里需要利用非类型模板参数

            4. 所开的空间是以整型为单位开辟,所以确认了所需的比特位后,还需计算是多少个int(32个比特位)大小,如果换算为int大小,有余数的话,就应该多开一个int大小

            template     //非类型模板参数
            class bitset
            {
            public:
            	bitset()
            	{
            		_bitset.resize(N/32+1, 0);  //所需开的空间,因为空间都只能以整型为单位开,所以需要除以32
            	}
            	void set(size_t x)       //将x对应的比特位置1
            	{
            		size_t i = x / 32;    //确定是第几个int
            		size_t j = x % 32;    //确定是该int里面的第几个比特位
            		_bitset[i] |= (1 
            		size_t i = x / 32;
            		size_t j = x % 32;
            		_bitset[i] &= ~(1 
            		size_t i = x / 32;
            		size_t j = x % 32;
            		return _bitset[i] & (1 
            	size_t operator()(const string& s)
            	{
            		size_t hash = 0;
            		for (auto ch : s)
            		{
            			hash *= 131;
            			hash += ch;
            		}
            		return hash;
            	}
            };
            struct Func2
            {
            	size_t operator()(const string& s)
            	{
            		size_t hash = 0;
            		for (size_t i = 0; i 
VPS购买请点击我

免责声明:我们致力于保护作者版权,注重分享,被刊用文章因无法核实真实出处,未能及时与作者取得联系,或有版权异议的,请联系管理员,我们会立即处理! 部分文章是来自自研大数据AI进行生成,内容摘自(百度百科,百度知道,头条百科,中国民法典,刑法,牛津词典,新华词典,汉语词典,国家院校,科普平台)等数据,内容仅供学习参考,不准确地方联系删除处理! 图片声明:本站部分配图来自人工智能系统AI生成,觅知网授权图片,PxHere摄影无版权图库和百度,360,搜狗等多加搜索引擎自动关键词搜索配图,如有侵权的图片,请第一时间联系我们,邮箱:ciyunidc@ciyunshuju.com。本站只作为美观性配图使用,无任何非法侵犯第三方意图,一切解释权归图片著作权方,本站不承担任何责任。如有恶意碰瓷者,必当奉陪到底严惩不贷!

目录[+]