布隆過濾器:它實際上是一個很長的二進制向量和一系列隨機映射函數。用於檢索一個元素是否在一個集合中。它的優點是空間效率和時間效率都遠遠超過一般算法。缺點是有一定的誤識率,和刪除困難。
原理:當一個元素加入集合時,通過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;
}