布隆过滤器的实现(c++)

简要介绍一下布隆过滤器:

如果想要判断一个元素是不是在一个集合里,一般想到的是将所有元素保存起来,然后通过比较确定。链表,树等等数据结构都是这种思路. 但是随着集合中元素的增加,我们需要的存储空间越来越大,检索速度也越来越慢(O(n),O(logn))。不过世界上还有一种叫作散列表(又叫哈希表,Hash table)的数据结构。它可以通过一个Hash函数将一个元素映射成一个位阵列(Bit array)中的一个点。这样一来,我们只要看看这个点是不是1就可以知道集合中有没有它了。这就是布隆过滤器的基本思想。(摘自百度百科)       

实现:

1.计算需要的哈希函数个数k及需要申请的内存长度m(m是二进制长度 ,申请时可以申请((m/32)+1   个int 类型),

2.将文件中的每一个样本经k个哈希函数求得k个哈希值 ,并对每一个哈希值取模(哈希值%m),并将申请的内存中对应位置1(如果本来是1,则不改变),

3.判断某样本是否存在,只需重复第二步,根据哈希函数计算每一个哈希值,取模并看内存中的每个对应位是否为1。

 

查找的时间复杂度为O(1)。

且并不能保证零失误率(本来在集合里的元素一定可以判断正确,但是不在集合中的元素也有可能判断为在集合中)。

 

下图为m,k的计算公式,其中n为样本数量,p为样本失误率,k为需要哈希函数的个数,m为需要申请的内存长度(注意是二进制)。

P真为  真实的失误率。

布隆过滤器的实现(c++)_第1张图片

代码如下:

#ifndef _BLOOMFILTER_
#define _BLOOMFILTER_

#include
#include
using namespace std;
unsigned int SDBMHash(const char *str);
unsigned int RSHash(const char *str);
unsigned int JSHash(const char *str);
unsigned int PJWHash(const char *str);
unsigned int APHash(const char *str);
unsigned int DJBHash(const char *str);
unsigned int ELFHash(const char *str);
unsigned int BKDRHash(const char *str);
class Bloomfilter{
public:
	Bloomfilter(double err_rate,int num,char* path);	//传入样本的文档路径,样本个数,期望的失误率,注意计算得到的哈希函数个数k需要不大于hashtable的size
    ~Bloomfilter();
    bool is_contain(const char* str);	//查看字符串是否在样本中存在
    int hashnum();				//返回k
       // double real_precision();	//返回真实的失误率
    int sizeofpool();				//返回len
	void filter_init();		//初始化布隆过滤器
private:
	void listinit();				//打开path路径的文档,计算每一行样本到内存bitpool中
	int  hashtable_init();			//把几个哈希函数加入到vector hastable容器中,必须大于k
	int len; 
	char* mypath;			//文件的路径,通过构造函数传入路径
    Bloomfilter()=delete;
    double precision;
    int *bitpool;		//需要内存的长度,在构造函数中申请
	int bitpoollen;		//需要的二进制位数m
	int hashfuncnum;	//需要的哈希函数的个数k, k <=hashtable.size();
	int samplenum;		//样本个数,构造函数传入
	vector hashtable;	//存放计算字符串哈希值的哈希函数
};
#endif
#include
#include
#include
#include
#include"bloomfilter.h"
#include
double lg2(double n)
{
	return log(n)/log(2);
}


using namespace std;

int Bloomfilter::hashtable_init()
{
	hashtable.push_back(*PJWHash);
	hashtable.push_back(*JSHash);
	hashtable.push_back(*RSHash);
	hashtable.push_back(*SDBMHash);
	hashtable.push_back(*APHash);
	hashtable.push_back(*DJBHash);
	hashtable.push_back(*BKDRHash);
	hashtable.push_back(*ELFHash);
	return hashtable.size();

}



Bloomfilter::Bloomfilter(double err_rate,int num,char* path)
{
	mypath=path;
	samplenum=num;
	bitpoollen=-((samplenum*log(err_rate))/(log(2)*log(2)));
	hashfuncnum=0.7*(bitpoollen/samplenum);
	len=bitpoollen/32+1;
	bitpool=new int[len];
}
int Bloomfilter::hashnum()
{

	return hashfuncnum;
}
int Bloomfilter::sizeofpool()
{

	return len;
}

void Bloomfilter::filter_init()
{
	hashtable_init();
	if(hashfuncnum>hashtable.size())
	{
		cout<<"哈系表中的函数不足,请添加"<

测试代码:

#include
#include"bloomfilter.h"

using namespace std;



int main()
{
	Bloomfilter mybloom(0.01,100,"redlist.txt");
	mybloom.filter_init();
	 cout<<"需要的哈希函数的个数 :"<

测试结果:

 

ps(篇幅有限,哈希函数的实现只把声明贴上了,定义自行百度);

 

谢谢阅读,欢迎指出错误!!

你可能感兴趣的:(数据结构与算法)