哈希的应用

一、位图

位图就是指使用一个比特位来表示某种事物的状态,适用于海量数据且无重复的场景,可以极大减少内存空间的使用。

1、使用场景

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

一个unsigned int 占四个字节的内存空间,49亿个就需要占4*40字节 = 14G,在32位系统中内存一共就4个G,而14个G都无法存储。

思路1:将40亿个数据保存在文件中,依次从文件中读取在进行比较。时间复杂度为O(N),读取文件存在IO操作,效率比较低。

思路2:将40亿个数据保存在文件中,在进行排序。效率更低。。。

思路3:位图。unsigned int最大值是42亿多,而这里的49亿个数据都是不重复的,我们可以考虑使用一个42位的位图对这些数据映射(值是多少就映射在对应的位置,占用的内存不超过2G),将要查找的数据进行判断即可。

2)快速查找某个数据是否在一个集合当中(同上)

3)排序

按照所给集合的最大值建立位图,再将集合进行映射,遍历位图,为1的位置表示存在的数据,这样得到的结果就是排序后的集合。

4)求集合的交集、并集

两个位图比较,或者一个位图另和集合直接进行比较。

2、位图模拟实现

二、布隆过滤器

位图在处理数字数据时,很方便处理,直接按值进行映射即可。而在处理string等类型时,需要进行hash映射,即将字符串转换成整型作为位图的下标进行映射,但是再好的哈希函数也难以避免hash冲突问题。布隆过滤器,实际上就是位图和hash的结合,不过它进行了一些特殊的处理,可以减少hash冲突。

1、布隆过滤器的概念

布隆过滤器是由布隆提出的一种紧凑型的、比较巧妙的概率型数据结构。特但是插入和查找都比较高效,用多个哈希函数将位图中的多个比特位映射一个数据,减少哈希冲突。但是相比常规存储数据,又可以节省空间。

如下图所示,一个数据data经过三个hash函数,映射在了三个不同的比特位。

2、布隆过滤器的操作

1)插入

使用多个hash函数,对同一个字符串进行hash计算,将计算出的结果作为下标,将位图中的对应位置置为1.这里,一般采用三个hash函数进行hash计算并映射即可。

如下图,表示将“baidu”和“tencent”通过hash函数计算后映射在位图中的位置。

2)查找

查找一个数据是否在布隆过滤器中,首先需要使用所有hash函数对数据进行计算,找到对应的下标,判断所有下标位置是否都为1,如果是则表示找到了否则表示没有找到(布隆过滤器中不存在这个数据)。

3)删除

布隆过滤器不可以进行删除操作。原因是,一个数据对应多个比特位,如果删除该数据对应的几个位图有可能导致其他数据在位图中查找不到。

例如:hash1("tencent") = 2 hash2("tencent") = 5 hash("tencent") = 8和hash1("baidu") = 2 hash2("baidu") = 9 hash3("baidu ") = 10分别表示使用布隆过滤器中的哈希函数对百度和腾讯计算得到的结果。如果删除“baidu”,不布隆过滤器中的2 9 10位置都会被删除,那么在里边查找"tencent"时,就查找不到了。

3、布隆过滤器的优缺点

优点:

  • 效率高:增加和查询数据的时间复杂度为O(K)k为hash函数的个数,与布隆过滤器中数据的个数无关。
  • 节省空间
  • 对特殊数据的处理减少hash冲突

缺点:

  • 查找数据存在误判情况(不在一定准确,在不一定准确)。可能一个数据使用hash映射出的位置都被其他不同的数据占用了,即使该数据不存在,使用布隆过滤器查找时也会认为存在
  • 不能删除数据

三、海量数据处理面试题

1、hash切割

给一个超过100G大小的log file, log中存着IP地址, 设计算法找到出现次数最多的IP地址? 

建立100个文件,编号分别为1~100,使用hash函数对IP地址进行计算,得到的结果为文件的编号,将IP地址存到对应的文件中,这样相同的IP肯定在一个文件中。在统计100个文件中出现次数最多的IP地址,再将这100个IP地址的出现次数比较,从而计算出出现次数最多的IP地址。

2、位图应用

1)给定100亿个整数,设计算法找到只出现一次的整数?

位图的变形,两个位图或者是两个比特位的位图。2个比特位可以表示4个数字,0表示一个数字不存在,1表示出现1次,2表示出现2次以上。在遍历位图,出现次数为1的就找到了。

2)给两个文件,分别有100亿个整数,我们只有1G内存,如何找到两个文件交集?

两个位图,分别映射两个文件,在比较两个位图。

3)位图应用变形:1个文件有100亿个int,1G内存,设计算法找到出现次数不超过2次的所有整数

同1)

3、布隆过滤器

1)给两个文件,分别有100亿个query,我们只有1G内存,如何找到两个文件交集?分别给出精确算法和近似算法

近似算法:使用布隆过滤器进行映射,在进行比较。

精确算法:hash切割,将一个文件切成若干个小文件,用另一个文件和这些小文件进行比较,就可以求出交集。

2)如何扩展BloomFilter使得它支持删除元素的操作因为不同的字符串可能会映射到相同的位,如果删除字符串更改位就会影响其它的字符串,因此可以把每个位标记成计数器。
那么到底用几个位来表示计数器呢?给的位如果少了,如果多个值映射到一个位置就会导致计数器溢出。比如1个byte最多计数到256,假设有260个值都映射到一个位置,就会出问题了。
但是如果使用更多的位去映射一个位置,空间消耗就会大。布隆过滤器特点就是节省空间。

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

疯狂嘚程序猿

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

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

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

打赏作者

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

抵扣说明:

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

余额充值