用Hash相关算法解决海量数据处理问题

用Hash相关算法解决海量数据处理问题

对于一个数据量为m的数据,调用n次contains问题。
(1)遍历
时间复杂度:O(m)*n == O(m*n)
(2)先排序,后二分查找
时间复杂度:O(m*log(m))(排序) + O(log(m))*n(查找) == O((m+n)*log(m))
(3)先保存HashSet,再查找:
时间复杂度:O(m) +O(1)*n == O(m+n)
空间复杂度:O(m)

1 位图来处理大数据问题:

位图思想引入:

int[] array = {3,4,1,2,5,9};
int[] count = new int[10];
for(int i=0;i<array.length;i++){
	count[array[i]]=1;
}
>>>count={0,1,1,1,1,1,0,0,0,1}

所谓位图,就是用每一位来存放某种状态:
我们需要存储的的是0或1,而上面的一个无符号的数要占用32位。所以我们可以使用一个二进制比特位来代表数据是否存在的信息,如果二进制比特位为1代表存在,为0代表不存在。如果有8W数据那么所需空间为32bit*8W,如果我们用1个bit来存储,那么所需的空间为1bit*8W
在这里插入图片描述

那么该如何用位图的方式保存记录m个数字呢?
(1)确定数组大小

int[] array = new int[向上取整(m/32)]

(2)将数据m中的某个数字n对应的bit位置1

index = 向下取整(n/32);
bit = n%32;
array[index] = array[index] | (1<<bit);

(3)将数据m中的某个数字n对应的bit位置0

array[index] = array[index] & (~(1<<bit));

(4)判断某个数对应的bit是1还是0(即判断某个数是否存在)

array[index]&(1<<bit)==0 ? 不存在 : 存在

举例:将12对应的bit位置1.

int[] array = new int[1];
index = 12/32=0;
bit = 12%32=12;
array[0] = array[0] | (1<<bit);

在这里插入图片描述

位图的应用

  1. 快速查找某个数据是否在一个集合中
  2. 排序
  3. 求两个集合的交集、并集等
  4. 操作系统中磁盘块标记

注意:

  • 位图法只能应用于无符号整数
  • 适用于海量数据,数据无重复的场景,通常是用来判断某个数据存不存在的。
2 布隆过滤器

当推荐系统推荐新闻时会从每个用户的历史记录里进行筛选,过滤掉那些已经存在的记录。如何快速查找呢?

  1. 用哈希表直接存储用户记录,缺点:浪费空间
  2. 用位图存储用户记录,缺点:容易产生哈希冲突
  3. 将哈希与位图结合,即布隆过滤器
(1)布隆过滤器的插入查询

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

在这里插入图片描述

布隆过滤器的思想是将一个元素用多个哈希函数映射到一个位图中,因此被映射到的位置的比特位一定为1。所以可以按照以下方式进行查找:分别计算每个哈希值对应的比特位置存储的是否为零,只要有一个为零,代表该元素一定不在哈希表中,否则可能在哈希表中。

注意:
布隆过滤器如果说某个元素不存在时,该元素一定不存在,如果该元素存在时,该元素可能存在,因为有些哈希函数存在一定的误判。

(2)布隆过滤器删除

布隆过滤器不能直接支持删除工作,因为在删除一个元素时,可能会影响其他元素。
比如:如果直接将该元素所对应的二进制比特位置0,那么如果有一个元素在多个哈希函数计算出的比特位上和该元素刚好有重叠,那么相当于也将该元素删除了。

删除的方法:将布隆过滤器中的每个比特位扩展成一个小的计数器,插入元素时给k个计数器(k个哈希函数计算出的哈希地址)加一,删除元素时,给k个计数器减一,通过多占用几倍存储空间的代价来增加删除操作。

缺陷:

  1. 无法确认元素是否真正在布隆过滤器中
  2. 存在计数回绕

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

(4)布隆过滤器缺陷
1)有误判率,即存在假阳性(False Position),即不能准确判断元素是否在集合中(补救方法:再建立一个白名单,存储可能会误判的数据);
2)不能获取元素本身;
3) 一般情况下不能从布隆过滤器中删除元素;
4)如果采用计数方式删除,可能会存在计数回绕问题;

注意:

  • 数据量较大时,常规方法主要是因为空间不够用导致的。
    位图能够提高空间利用率(无符号整数);
    布隆过滤器,能提高空间利用率,得到的解是概率解。
3 哈希切割

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

如果数据量不大可以采用HashMap计数法来解决。

为了处理海量数据,可以先对数据进行分割,将大数据分割成一个个小数据块。
切割时要保证相同的ip分到同一个小数据块中(通过哈希函数进行分割)。
在这里插入图片描述
(2)如何找到top K的IP?
首先通过哈希分割,将数据分配到每个桶中,用Hash统计每个桶中的IP数,之后用小顶堆求出每个桶中出现频率最高的前K个数,最后在所有的桶中求全局TopK

4 位图应用

(1)给定100亿个整数,设计算法找到只出现一次的整数?
分情况:没有出现、出现一次、出现一次以上

这是一个三元信息,而一个bit能存储二元信息,两个bit能存储四元信息。

我们可以用 00表示没有出现; 01表示出现一次;11表示出现一次以上。
将两个bit位进行异或,得到1时,即为出现了一次。

(2)1个文件有100亿个int,1G内存,设计算法找到出现次数不超过2次的所有整数。
这是一个四元信息:没有出现:00;出现一次:01;出现两次:10;出现两次以上:11

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值