數據結構之哈希擴展——布隆過濾器

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

下面使我們的測試結果
這裏寫圖片描述


如有錯誤請指出,謝謝

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章