布隆过滤器:它实际上是一个很长的二进制向量和一系列随机映射函数。用于检索一个元素是否在一个集合中。它的优点是空间效率和时间效率都远远超过一般算法。缺点是有一定的误识率,和删除困难。
原理:当一个元素加入集合时,通过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;
}