海量数据查重问题方案汇总

文章讨论了处理海量数据查重问题的几种方法,包括使用哈希表、分治策略以及BloomFilter。哈希表用于快速查找重复项,但在内存有限时遇到挑战;分治思想将大文件拆分为小文件处理,避免一次性加载所有数据;BloomFilter则是在内存有限情况下,提供一种低错误率的元素存在性判断工具,但不支持删除操作。
摘要由CSDN通过智能技术生成

海量数据的查重问题主要思路

问题如:哈希表 50亿(5G)个整数(20GB),链式哈希表一个节点有数据域和地址域,故还需额外20GB,总共40GB

  1. 分治思想
  2. Bloom Filter:布隆过滤器(判定不存在)
  3. 字符串类型:TrieTree字典树(前缀树)

哈希表法

参考代码如下

int main()
{
	const int SIZE = 10000;
	int arr[SIZE] = { 0 };
	for (int i = 0; i < SIZE; ++i)
	{
		arr[i] = rand() % 500;
	}

	unordered_map<int, int> map;
	for (int val : arr)
	{
		map[val]++;
	}

	for (auto pair : map)
	{
		if (pair.second > 1)
		{
			cout << "数字:" << pair.first << " 重复次数:" << pair.second << endl;
		}
	}
	return 0;
}

分治思想

场景1

有一个文件,有50亿个整数(或IP地址),内存限制400M,让你找出文件中重复的元素,以及重复次数

分析:

首先直接将文件放到内存肯定不现实,用链式哈希表存50亿个数约为5G*4B = 20GB,再加指针域也是4B,一共约40GB,超出题目要求。所以采用分治的思想:
将大文件分成小文件,使得每个小文件能加入到内存中,求出对应的重复元素,把结果写入到一个存储重复元素的文件中。

大文件=》小文件(40G/400M = 120个 小文件),分别起名为data0.txt,data1.txt,data2.txt … data126.txt

遍历大文件元素,把每个元素根据哈希映射函数,放到对应序号的小文件中:即data % 127 = file_index. (值相同的通过一样哈希函数,肯定是放在同一个小文件中)

场景2

a,b两个文件,里面都有10亿个整数(如IP地址),内存限制400M,求出两个文件中重复的元素。

分析

10亿个数放在内存就最少要8GB左右空间,完全不合题意,所以采用分治的思路。

10亿文件 = 1G*4 B ,采用链式哈希表则要4G * 2 =8GB空间,划分文件(8G/400M)为27个小文件

a文件全部读到内存中,存储到哈希表;

从b文件读取数据,在内存哈希表中查询

把a和b两个大文件划分成个数相等的一系列小文件:
a0.txt b0.txt

a1.txt b1.txt

a2.txt b2.txt

a26.txt b26.txt

从a文件中读数据,通过 data % 27 = file_index

从b文件中读数据,通过 data % 27 = file_index

从a和b两个文件中数据相同的元素,进行哈希映射后必然在相同的文件中,故

a1和b1进行查重,a2和b2进行查重…a26和b26进行查重

Bloom Filter布隆过滤器

在内存有限的情况下,快速判断一个元素是否在一个集合中,可用布隆过滤器。

通俗的来讲,在使用哈希表比较占内存时,它是一种更高级的“位图法”,没有位图法的缺陷(数字少但数字最大值大导致开辟空间大)。

Bloom Filter要点:

  • Bloom Filter是由一个位数组+k个哈希函数构成
  • Bloom Filter空间和时间利用率很高,但它有一定错误率,虽然错误率很低,Bloom Filter判断某一个元素不在一个集合里,那该元素肯定不在集合中;Bloom Filter判断某个元素在一个集合里,那该元素可能在,也可能不在。
  • Bloom Filter查找错误率和位数组大小,以及哈希函数的个数有关系,
  • Bloom Filter默认只支持addquery操作,不支持delete操作(因为存储的状态位可能是其他**数据状态位,**删除导致其他元素查找判断出错)
  • Bloom Filter增加元素过程:把元素的值通过k个哈希函数进行计算,得到k个值,将这些值对应的位置1
  • Bloom Filter查询元素过程:把元素的值通过k个哈希函数进行计算,得到k个值,查看对应位的值是否为1,若有一个为0,表示必然不存在;若都为1,则表示可能存在
  • 用Bloom Filter解决上面问题就是:用a文件数据构建Bloom Filter的位数组中的状态值,然后再读取b文件的数据进行Bloom Filter的查询
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值