每日一题——布隆过滤器

来源:互联网 发布:卓越集团 知乎 编辑:程序博客网 时间:2024/06/05 14:49

布隆过滤器:它实际上是一个很长的二进制向量和一系列随机映射函数。用于检索一个元素是否在一个集合中。它的优点是空间效率和时间效率都远远超过一般算法。缺点是有一定的误识率,和删除困难。
原理:当一个元素加入集合时,通过K个Hash函数将该元素映射成一个位阵列中的K个点,把他们置为1,检索时,只要看看这些点是不是都是1就可以知道它存在不。
如果有一个不为1,则该元素肯定不存在;
如果全是1,则该元素可能存在。

应用:URL去重,垃圾邮件处理
实现:

//哈希函数template<class K>class HashFuncDef{public:    size_t operator()(const K& key)        return key; }static size_t BKDRHash(const char* str){    unsigned int seed = 131;    unsigned int hash = 0;    while(*str)        hash = hash*seed+(*str++);    return (hsah & 0x7FFFFFFF);}template<>class HashFunDef<string>{public:    size_t operator()(const string& key)    {        return BKDRHash(key.c_str());    }};size_t SDBMHash(const char* str){    register size_t hash = 0;    while (size_t ch = (size_t)*str++)    {        hash = 65599 * hash + ch;        //hash = (size_t)ch+(hash<<6)+ (hash<<16)-hash;    }    return hash;}size_t RSHash(const char *str){    register size_t hash = 0;    size_t magic = 63689;    while (size_t ch = (size_t)*str++)    {        hash = hash * magic + ch;        magic *= 378551;    }    return hash;}size_t APHash(const char* str){    register size_t hash = 0;    size_t ch;    for (long i = 0; ch = (size_t)*str++; i++)    {        if (0 == (i & 1))        {            hash ^= ((hash << 7) ^ (hash >> 3));        }        else        {            hash ^= (~((hash << 11) ^ ch ^ (hash >> 5)));        }    }    return hash;}size_t JSHash(const char* str){    if (!*str)        return 0;    register size_t hash = 1315423911;    while (size_t ch = (size_t)*str++)    {        hash ^= ((hash << 5) + ch + (hash >> 2));    }    return hash;}template<class K>struct __HashFunc1{    size_t operator()(const K& key)    {        return BKDRHash(key.c_str());    }};template<class K>struct __HashFunc2{    size_t operator()(const K& key)    {        return SDBMHash(key.c_str());    }};template<class K>struct __HashFunc3{    size_t operator()(const K& key)    {        return RSHash(key.c_str());    }};template<class K>struct __HashFunc4{    size_t operator()(const K& key)    {        return APHash(key.c_str());    }};template<class K>struct __HashFunc5{    size_t operator()(const K& key)    {        return JSHash(key.c_str());    }};//实现布隆过滤器template<class K,class HashFunc = _HashFunc1<string>>class BloomFile{public:    BloomFile(size_t size)        :_map(size)    {}    bool Insert(string str)    {        size_t idx1 = _HashFunc1()(str);        size_t idx2 = _HashFunc2()(str);        size_t idx3 = _HashFunc3()(str);        size_t idx4 = _HashFunc4()(str);        size_t idx5 = _HashFunc5()(str);        _map.Set(idx1);        _map.Set(idx2);        _map.Set(idx3);        _map.Set(idx4);        _map.Set(idx5);    }       bool Find(string str)    {        size_t idx1 = _HashFunc1()(str);        size_t idx2 = _HashFunc2()(str);        size_t idx3 = _HashFunc3()(str);        size_t idx4 = _HashFunc4()(str);        size_t idx5 = _HashFunc5()(str);        if(!_map.Test(idx1)) return false;        if(!_map.Test(idx2)) return false;        if(!_map.Test(idx3)) return false;        if(!_map.Test(idx4)) return false;        if(!_map.Test(idx5)) return false;        return true;    }private:    BitMap _map;}