数据结构之哈希扩展——布隆过滤器

背景:在日常生活中,包括在设计计算机软件时,我们要经常判断一个字符串是否在一个集合中,一个英语单词是否拼写正确。最直接的办法就是将集合中的所有元素都存在计算机中,遇到一个新元素,将它和集合中的元素直接比较即可。一般来讲计算机中的集合是用哈希表来存储的,它的好处就是快速准确,缺点是费存储空间。以空间换时间。我们只需要看看所查的点是不是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;
}

下面使我们的测试结果
这里写图片描述


如有错误请指出,谢谢

猜你喜欢

转载自blog.csdn.net/mignatian/article/details/80419490