每日一題——布隆過濾器

布隆過濾器:它實際上是一個很長的二進制向量和一系列隨機映射函數。用於檢索一個元素是否在一個集合中。它的優點是空間效率和時間效率都遠遠超過一般算法。缺點是有一定的誤識率,和刪除困難。
原理:當一個元素加入集合時,通過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;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章