介绍:
Bloom filter 是一种节约空间的数据结构,用于检测元素是否为集合的成员。Bloom filter可能误判,但不会漏判,所以可以用于判断:
“元素是否在集合中(有一定错误概率)”
“元素一定不在集合中(找到所有可能在的,剩下就是一定不在的)”。
误判的概率随着元素数目增多而变大。
算法描述:
一个空的Bloom filter含有m个bit,每个bit置为0。另外定义k个不同hash函数,将元素集映射到m个位置。
typedef struct {
size_t asize;
unsigned char *a;
size_t nfuncs;
hashfunc_t *funcs;
} BLOOM;
add 操作:将输入元素经k个hash函数分别映射到k个位置,并将这些位置的bit都置1。
int bloom_add(BLOOM *bloom, const char *s)
{
size_t n;
for(n=0; n<bloom->nfuncs; ++n) {
SETBIT(bloom->a, bloom->funcs[n](s)%bloom->asize);
}
return 0;
}
query 操作:将输入元素经k个hash函数分别映射到k个位置,若这k个位置对应的bit全为1,则该元素可能存在。若这k个bit中存在0,则该元素一定不在集合中。
int bloom_query(BLOOM *bloom, const char *s)
{
size_t n;
for(n=0; n<bloom->nfuncs; ++n) {
if(!(GETBIT(bloom->a, bloom->funcs[n](s)%bloom->asize))) return 0;
}
return 1;
}
案例:a,b 两个文件中各存有50亿个URL,找出两个文件中相同的URL。内存只有4个G。
方案:用Bloom filter算法,由于4G内存一共有4*1024*1024*1024*32=340亿个bit,所以可以建立m=340亿的bits array。先遍历a文件,对50亿个URL执行add操作,然后再遍历b文件,对50个URL执行query操作,所有匹配的元素即为所求。