背景:在日常生活中,包括在设计计算机软件时,我们要经常判断一个字符串是否在一个集合中,一个英语单词是否拼写正确。最直接的办法就是将集合中的所有元素都存在计算机中,遇到一个新元素,将它和集合中的元素直接比较即可。一般来讲计算机中的集合是用哈希表来存储的,它的好处就是快速准确,缺点是费存储空间。以空间换时间。我们只需要看看所查的点是不是1就可以知道集合里面有没有它了。
但是因为哈希冲突的问题,所以我们设计了很多函数来尽量降低冲突率,多个哈希函数,如果他们有一个元素不在集合中,那就说明它不在集合里,只有都在的情况下才说明它在集合里
下面就是我们的布隆过滤器的简单实现
bloomfilter.h
#pragma once
#include "bitmap.h"
#define BITMAPMAXSIZE 10000
#define bloomhashcount 2
typedef uint64_t(*bloomhash)(const char*);
typedef struct bloomfilter{
bitmap bm;
bloomhash bloom_hash[bloomhashcount];
}bloomfilter;
void bloomfilterinit(bloomfilter *bf);
void bloomfilterdestroy(bloomfilter *bf);
void bloomfilterinsert(bloomfilter *bf,const char *str);
int bloomfilterisexist(bloomfilter *bf,const char *str);
bloomfilter.c
#include "bloomfilter.h"
#include "bitmap.c"
size_t BKDRHash(const char *str)
{
size_t hash = 0;
size_t ch = 0;
while(ch = (size_t)*str++)//此函数的计算方式就是依次取字符串的ASCLL码
{
hash = hash * 131 + ch;
}
return hash;
}
size_t SDBMHash(const char *str)
{
size_t hash = 0;
size_t ch = 0;
while(ch = (size_t)*str++)//此函数的计算方式就是依次取字符串的ASCLL码
{
hash = hash * 65599 + ch;
}
return hash;
}
void bloomfilterinit(bloomfilter *bf)
{
if(bf == NULL)
{
return;
}
bitmapinit(&bf->bm,10000);
bf->bloom_hash[0] = SDBMHash;
bf->bloom_hash[1] = BKDRHash;
return;
}
void bloomfilterdestroy(bloomfilter *bf)
{
if(bf == NULL)
{
return;
}
bitmapdestroy(&bf->bm);
bf->bloom_hash[0] = NULL;
bf->bloom_hash[1] = NULL;
return;
}
void bloomfilterinsert(bloomfilter *bf,const char *str)
{
if(bf == NULL || str == NULL)
{
return;
}
uint64_t i = 0;
for(;i < bloomhashcount;i++)
{
uint64_t hash = bf->bloom_hash[i](str)%BITMAPMAXSIZE;
bitmapset(&bf->bm,hash);
}
return;
}
int bloomfilterisexist(bloomfilter *bf,const char *str)
{
if(bf == NULL || str == NULL)
{
return 0;
}
uint64_t i = 0;
for(;i < bloomhashcount;i++)
{
uint64_t hash = bf->bloom_hash[i](str)%BITMAPMAXSIZE;
int ret = bitmaptest(&bf->bm,hash);
if(ret == 0)
{
return 0;
}
}
return 1;
}
//test
//
#define HEADER printf("\n============%s============\n",__FUNCTION__)
void bloomfiltertest()
{
HEADER;
bloomfilter bloom;
bloomfilterinit(&bloom);
bloomfilterinsert(&bloom,"hehe");
bloomfilterinsert(&bloom,"haha");
int ret = bloomfilterisexist(&bloom,"he
he");
printf("expected ret is 1,actul is %d\n",ret);
}
int main()
{
bloomfiltertest();
return 0;
}
下面使我们的测试结果
如有错误请指出,谢谢