背景:在日常生活中,包括在設計計算機軟件時,我們要經常判斷一個字符串是否在一個集合中,一個英語單詞是否拼寫正確。最直接的辦法就是將集合中的所有元素都存在計算機中,遇到一個新元素,將它和集合中的元素直接比較即可。一般來講計算機中的集合是用哈希表來存儲的,它的好處就是快速準確,缺點是費存儲空間。以空間換時間。我們只需要看看所查的點是不是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;
}
下面使我們的測試結果
如有錯誤請指出,謝謝