布隆过滤器的简单实现
布隆过滤器(BloomFilter)是1970年由布隆提出的,它实际上是一个很长的二进制向量和一系列随机映射函数
布隆过滤器可以用于检索一个元素是否在一个集合中,它的优点是空间效率和查询时间都远远超过一般的算法,缺点
是有一定的误识别率和删除困难。
布隆过滤器(Bloom Filter)的适用范围如下:
实现数据字典,数据的判重,或者集合求交集
基本原理如下:
它的内容是,一个位图加上k个独立的hash函数,通过k个hash函数,可以得到khash函数对应的值,
然后把这些hash函数对应的值存入位图中(把具体的某一位置为1),然后查找时,通过判断k个hash
函数对应的位是不是为1,如果有一个为1,就代表该元素不存在,如果全为1,则该元素很可能存在
结构体代码如下:
#define HASHFUNCMAXSIZE 2
#define BitMapCapacity 1024
typedef struct BitMap{
uint64_t* data;
size_t capacity;
}BitMap;
/*字符串哈希函数*/
typedef size_t(*HashFunc)(const char*);
typedef struct BloomFilter{
BitMap bitmap;
HashFunc hash_func[HASHFUNCMAXSIZE];
}BloomFilter;
接下来看具体怎么实现:
初始状态时,有一个包含m位的数组每一位都设置为0:
初始化代码如下:
/*哈希函数*/
size_t hashfunc0(const char* str) {
assert(str);
size_t hash = 0;
size_t ch = 0;
while (ch = (size_t)*str++) {
hash = hash * 131 + ch;
}
return hash;
}
size_t hashfunc1(const char* str) {
assert(str);
size_t hash = 0;
size_t ch = 0;
while (ch = (size_t)*str++) {
hash = hash * 65599 + ch;
}
return hash;
}
/*初始化布隆过滤器*/
void BloomFilterInit(BloomFilter* bf) {
if (bf == NULL) {
return;
}
/*初始化位图*/
BitMapInit(&bf->bitmap, BitMapCapacity);
/*初始化哈希函数*/
bf->hash_func[0] = hashfunc0;
bf->hash_func[1] = hashfunc1;
}
我这里只用了两个哈希函数,比较少,容易出现哈希冲突
继续解释布隆过滤器,为了表达S={x1, x2,…,xn}这样一个