布隆过滤器

布隆过滤器的概念
如果想要判断一个元素是不是在一个集合里,一般想到的是将所有元素保存起来,然后通过比较确定。 链表 ,树等等数据结构都是这种思路. 但是随着集合中元素的增加,我们需要的存储空间越来越大,检索速度也越来越慢(O(n),O(logn))。不过世界上还有一种叫作散列表(又叫 哈希表 ,Hash table)的数据结构。它可以通过一个 Hash函数 将一个元素映射成一个位阵列(Bit array)中的一个点。这样一来,我们只要看看这个点是不是1就可以知道集合中有没有它了。这就是布隆过滤器的基本思想。
Hash面临的问题就是冲突。假设Hash函数是良好的,如果我们的位阵列长度为m个点,那么如果我们想将冲突率降低到例如 1%, 这个散列表就只能容纳m / 100个元素。显然这就不叫空间效率了(Space-efficient)了。解决方法也简单,就是使用多个Hash,如果它们有一个说元素不在集合中,那肯定就不在。如果它们都说在,虽然也有一定可能性它们在说谎,不过直觉上判断这种事情的 概率是比较低的。
本文算法思路来自https://segmentfault.com/a/1190000002729689
代码实现
BitMap.h
#pragma  once
#include<vector>
#include<iostream>
using namespace std;
class BitMap
{
public:
	BitMap(size_t range)
	{
		_bitMap.resize((range>>5) +1);
	}
	void Set(size_t x)
	{
		size_t index=x>>5;
        size_t num =x%32;
		/*size_t tmp=1;
		tmp<<=num;*/
		//_bitMap[index]|=tmp;
		_bitMap[index]=(1<<num);
	}
	void Reset(size_t x)
	{
		size_t index=x>>5;
		size_t num =x%32;
		size_t tmp=0;
		tmp<<=num;
		_bitMap[index] &=(~(tmp));
	}
	bool Test(size_t x)
	{
		size_t index=x>>5;
		size_t num =x%32;
		size_t tmp=1;
		tmp<<=num;
		_bitMap[index] &=tmp;
		return _bitMap[index];
	}
	~BitMap()
	{}
protected:
	vector<size_t> _bitMap;
};
BloonFilter.h
#pragma  once
#include <iostream>
#include <string>
#include <vector>
#include "BitMap.h"
using namespace std;
struct  __HashFunc1
{
	size_t BKDRHash(const char *str)  
	{  
		register size_t hash = 0;  
		while (size_t ch = (size_t)*str++)  
		{         
			hash = hash * 131 + ch;   // 也可以乘以31、131、1313、13131、131313..           
		}  
		return hash;  
	}  
	size_t operator()(const string& str)
	{
		return BKDRHash(str.c_str());
	}
};
struct  __HashFunc2
{
	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 operator()(const string& str)
	{
		return SDBMHash(str.c_str());
	}
};
struct  __HashFunc3
{
	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 operator()(const string& str)
	{
		return RSHash(str.c_str());
	}
};
struct  __HashFunc4
{
	size_t APHash(const char *str)  
	{  
		register size_t hash = 0;  
		size_t ch;  
		for (long i = 0; ch = (size_t)*str++; i++)  
		{  
			if ((i & 1) == 0)  
			{  
				hash ^= ((hash << 7) ^ ch ^ (hash >> 3));  
			}  
			else  
			{  
				hash ^= (~((hash << 11) ^ ch ^ (hash >> 5)));  
			}  
		}  
		return hash;  
	}  
	size_t operator()(const string& str)
	{
		return APHash(str.c_str());
	}
};
struct  __HashFunc5
{
	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;  
	}  
	size_t operator()(const string& str)
	{
		return JSHash(str.c_str());
	}
};
template<class K=string
,class HashFunc1=__HashFunc1
,class HashFunc2=__HashFunc2
,class HashFunc3=__HashFunc3
,class HashFunc4=__HashFunc4
,class HashFunc5=__HashFunc5>
class RefBloomFilter
{
public:
	RefBloomFilter(size_t num)
		:_range(num*5)
		,_bitMap(num*5)
	{}
	void Set(const K& key)
	{
		size_t index1=HashFunc1()(key)%_range;
		size_t index2=HashFunc2()(key)%_range;
		size_t index3=HashFunc3()(key)%_range;
		size_t index4=HashFunc4()(key)%_range;
		size_t index5=HashFunc5()(key)%_range;
		_bitMap.Set(index1);
		_bitMap.Set(index2);
		_bitMap.Set(index3); 
		_bitMap.Set(index4);
		_bitMap.Set(index5);  
		cout<<index1<<endl;
		cout<<index2<<endl;
		cout<<index3<<endl;
		cout<<index4<<endl;
		cout<<index5<<endl<<endl;

		
	}
	bool Reset(const K& key)
	{
		size_t index1=HashFunc1()(key)%_range;
		size_t index2=HashFunc2()(key)%_range;
		size_t index3=HashFunc3()(key)%_range;
		size_t index4=HashFunc4()(key)%_range;
		size_t index5=HashFunc5()(key)%_range;
		if(_bitMap[index1]==0
			||_bitMap[index2]==0
			||_bitMap[index3]==0
			||_bitMap[index4]==0
			||_bitMap[index5]==0)
			return false;
		_bitMap.Reset(index1);
		_bitMap.Reset(index2);
		_bitMap.Reset(index3);
		_bitMap.Reset(index4);
		_bitMap.Reset(index5);
		cout<<index1<<endl;
		cout<<index2<<endl;
		cout<<index3<<endl;
		cout<<index4<<endl;
		cout<<index5<<endl<<endl;
		return true;
	}
	bool Test(const K& key)
	{
		size_t index1=HashFunc1()(key)%_range;
		size_t index2=HashFunc2()(key)%_range;
		size_t index3=HashFunc3()(key)%_range;
		size_t index4=HashFunc4()(key)%_range;
		size_t index5=HashFunc5()(key)%_range;
		if(_bitMap.Test(index1)!=0
			&&_bitMap.Test(index2)!=0
			&&_bitMap.Test(index3)!=0
			&&_bitMap.Test(index4)!=0
			&&_bitMap.Test(index5)!=0)
		{
			cout<<index1<<endl;
		cout<<index2<<endl;
		cout<<index3<<endl;
		cout<<index4<<endl;
		cout<<index5<<endl<<endl;
			return true;
		
		}
		cout<<index1<<endl;
		cout<<index2<<endl;
		cout<<index3<<endl;
		cout<<index4<<endl;
		cout<<index5<<endl<<endl;
		return false;
	}
protected:
	BitMap _bitMap;
	size_t _range;
};
void test()
{
	RefBloomFilter<> bf(1);
	char* str1="http://blog.csdn.net/shangguan_1234";
	char* str2="http://blog.csdn.net/shangguan_1235";
	char* str3="http://blog.csdn.net/shangguan_1233";
	char* str4="http://blog.csdn.net/shangguan_1232";
	char* str5="http://blog.csdn.net/shangguan_1231";
	bf.Set(str1);
	bf.Set(str2);
	bf.Set(str3);
    bf.Set(str4);
	bf.Set(str5);
	cout<<bf.Test(str1)<<endl;
	cout<<bf.Test(str2)<<endl;
	cout<<bf.Test(str3)<<endl;
	cout<<bf.Test(str4)<<endl;
	cout<<bf.Test(str5)<<endl;
}

test.cpp
#include "BloomFilter.h"
int main()
{
	test();
	system("pause");
	return 0;
}




  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值