赞
踩
对于处理海量数据,内存中放不下的数据一般有两种方法:
1.考虑特殊数据结构(位图、布隆过滤器)
2.切割(哈希切割、平均切割)
对于这类问题可以画图+文字+伪代码说明问题。
一:哈希切割topK问题:
给一个超过100G大小的log file,log中存放着IP地址,设计算法找到出现次数最多的IP地址?如何找到top K的IP?
对于本题采用哈希切割:
二:位图应用:
**给定100亿个整数,设计算法找到只出现一次的整数?
一个文件有100亿个int,1G内存,设计算法找到出现次数不超过2次的整数?**
本题利用数据结构位图:
解释如何设置次数:
代码如下:
#include<stdio.h>
#include<assert.h>
#include<windows.h>
typedef struct TwoBitSet
{
size_t *bts;//数组
size_t range;//数据的范围
}TwoBitSet;
void TBSInit(TwoBitSet *tbs,size_t range)
{
assert(tbs);
//需要两位表示一个数据,所以除以16,(range >> 4) + 1计算需要多少个整型
tbs->bts = (size_t *)malloc(((range >> 4) + 1) * sizeof(size_t));
assert(tbs->bts);
memset(tbs->bts, 0,((range >> 4) + 1) * sizeof(size_t));
tbs->range = range;
}
int TBSGetValue(TwoBitSet *tbs, size_t x)//
{
assert(tbs);
size_t index = x >> 4;//计算x在数组里下标
size_t num = x % 16 * 2;//因为两位表示一位,需要乘2
int value = tbs->bts[index];//不能改变tbs->bts[index],所以设置value
value >>= num;//将value向右移
return value & 3;//任何数和3(11)&为任何数
}
void TBSSetVaule(TwoBitSet *tbs, size_t x, size_t value)//设置值
{
assert(tbs);
size_t index = x >> 4;//计算x在数组里下标
size_t num = x % 16 * 2;//因为两位表示一位,需要乘2
if (value == 0)//设置为00
{
//先将3左移到要设置的位,然后取反,保证在这两位为0,然后&,这两位为0,其他为不变
tbs->bts[index] &= ~(3 << num);
}
else if (value == 1)//要设置为01
{
tbs->bts[index] |= (1 << num);//设置1
tbs->bts[index] &= ~(1 << (num + 1));
}
else if (value == 2)//要设置为10
{
tbs->bts[index] |= (1 << (num + 1));//设置1
tbs->bts[index] &= ~(1 << num);//设置0
}
else if (value == 3)//要设置为11
{
tbs->bts[index] |= (3 << num);
}
}
void BTSDestory(TwoBitSet *tbs)//销毁
{
assert(tbs);
free(tbs->bts);
tbs->bts = NULL;
tbs->range = 0;
}
给两个文件,分别有100亿个整数,只有1G内存,如何找到两个文件的交集?
本题利用数据结构位图:
如上个题:一个文件500M,文件A中数据出现一次将位图1中该位设置为1,再出现不用设置;文件B中数据出现一次将位图2中该位设置为1,再出现不用设置(一个整型32位,存32个数据),然后位图1&位图2,&结果为1的位则是两个文件的交集。
三:布隆过滤器:
给两个文件,分别有100亿个query,只有1G内存,如何找到两个文件的交集?分别给出精确算法和近似算法。
我们知道,布隆过滤器算法可以存储任意类型数据,尤其适用字符串,所以对于近似算法可以直接利用布隆过滤器,将query利用哈希函数放到布隆中,但这样误判率较大,可能该位置是其他字符串。所以,精确算法如下:
100亿个query,假设平均每个query占30字节,100亿个query占300G(10亿字节=1G,100亿*30字节=3000亿字节=300G)
*如何扩展BloomFilter使得它支持删除元素的操作?
如何扩展BloomFilter使得它支持计数操作?*
因为一个布隆过滤器的Key对应多个位,冲突的概率较大,所以不支持删除,因为删除有可能影响其他元素,如果要对其元素进行删除,就不得不对每一个位进行引用计数:
四:倒排索引
给上千个文件,每个文件大小为1K—100M。给n个词,设计算法对每个词找到包含它 的文件,只有100K内存?
输入需要查询的key:先找到映射位置,然后会根据key在每个文件出现次数将出现次数多的文件放在前面。
以上为海量数据如何处理的分析。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。