位图和哈希切分的大数据处理

本文探讨了位图在大数据集处理中的高效应用,例如快速判断一个数是否存在于40亿个无序整数中,并通过实例代码演示。此外,还讨论了使用哈希切分解决大规模日志文件中频繁出现的IP地址统计问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

位图是一个数组的每个数据的每个二进制位表示一个数据,0表示数据不存在,1表示数据存在;

在现实生活中,大数据的处理十分的常见;比如说,给40亿个不重复的无符号整数,没排过序,如何快速判断一个数是否在这40亿个数中?

要解决这个问题,我们首先想到的是先排序,在进行二分查找,很容易就可以判断成功。但是排序并不好排,40亿个数据,让我们来算一算需要多少的内存,40亿*4字节 =  4G*4 = 16G;一般的电脑都是4G,8G;一次处理16G的数据显然是不可能了;这就需要用位图来解决这类的问题了;

要表示40亿个数据,一个数据4个字节,32个二进制位,用一个二进制位来表示一个数是否存在的状态,这就需要500M左右的内存;显然这是可以接受的;具体看下图:

实现代码如下

//位图
class BitSet
{
public:
	BitSet(const size_t range)
	{
		_a.resize((range>>5) + 1);
	}

	void Set(size_t num)  //将num记录;
	{
		size_t index = num >> 5;
		size_t pos = num % 32;

		_a[index] |= (1 << pos);
	}

	void Reset(size_t num)  //删除num记录
	{
		size_t index = num >> 5;
		size_t pos = num % 32;

		_a[index] &= ~(1 << pos);
	}

	bool Test(size_t num) //判断num是否存在;
	{
		size_t index = num >> 5;
		size_t pos = num % 32;

		//判断这这个位,0不存在,1存在;

		return _a[index] & (1 << pos);
	}


protected:
	vector<int> _a;
};
解决上述问题的测试用例:

void TestBitSet()
{
	BitSet bs(-1); //-1转换后就是整数表示的最大范围;
	bs.Set(1);
	bs.Set(3);
	bs.Set(4);
	bs.Set(8);
        //.... 向后的40亿数据
	cout << bs.Test(1) << endl;
	cout << bs.Test(10) << endl;
}
让我们继续深入,看看另外一个问题:

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

一次处理100G,计算机想想就压力巨大,我们可以将其划分位计算机能处理的大小进行处理,比如以1G为单位划分位100份,一份一份进行处理,就可达到目的,但是怎么划分是个难题;

第一种思路:可以将100G等分划分位100份,每一份单独处理,但是这个会遇到一个问题,有些想同的IP地址是在不同的等分块中,统计的结果不是正确的结果;

第二种思路:利用哈希切分,可以划分成100份,重点是使相同IP进入一个编号相同的小文件;这就避免了相同IP地址分散在不同小文件的问题;



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值