【干货】位图的实现与布隆过滤器

位图是用一个btye位来表示一个数据是否存在,再通过哈希函数确定一个数据所在的位置,这样处理会使当仅需要判断一个数据在不在的时候大大的提高效率,缩小内存的使用,如一个数据为int型,而一个int型的数据构成的位图能表示32个数据的存在状态。代码实现如下:

Bitmap.h:

#include<vector>
class BitMap
{
public:
	BitMap(size_t size)
		:_size(0)
	{
		Size(size);
	}
	void Set(size_t key)
	{
		size_t index = key / 32;
		size_t offset = key % 32;
		_map[index]=_map[index] | (1 << offset);
		++_size;
	}
	void Reset(size_t key)
	{
		size_t index = key / 32;
		size_t offset = key % 32;
		if ((_map[index] >> offset) & 1)
		{
			_map[index] = _map[index] & (~(1 << offset));
			++_size;
		}
	}
	void Size(size_t size)
	{
		_map.resize(size);
	}
	bool Touch(size_t key)
	{
		size_t index = key / 32;
		size_t offset = key % 32;
		if ((_map[index] >> offset) & 1)
			return true;
		return false;
	}
protected:
	size_t _size;
	vector<size_t> _map;
};

布隆过滤器:布隆过滤器(Bloom Filter)是1970年由布隆提出的。它实际上是一个很长的二进制向量和一系列随机映射函数。布隆过滤器可以用于检索一个元素是否在一个集合中。它的优点是空间效率和查询时间都远远超过一般的算法,缺点是有一定的误识别率和删除困难。(百度百科)

这里所说的映射函数我们一般定义几个,这样就可以加大避免冲突的几率,这里我写了个key为string 类的布隆过滤器,仅供参考:

BloomFilter.h:

#include"BitMap.h"
size_t BKDRHash(const char *str)//这里定义了5个映射算法,仅供参考
{
	register size_t hash = 0;
	while (size_t ch = (size_t)*str++)
	{
		hash = hash * 131 + ch;           
	}
	return hash;
}
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 ((i & 1) == 0)
		{
			hash ^= ((hash << 7) ^ ch ^ (hash >> 3));
		}
		else
		{
			hash ^= (~((hash << 11) ^ ch ^ (hash >> 5)));
		}
	}
	return hash;
}
size_t JSHash(const char *str)
{
	if (!*str)        // 以保证空字符串返回哈希值0  
		return 0;
	register size_t hash = 1315423911;
	while (size_t ch = (size_t)*str++)
	{
		hash ^= ((hash << 5) + ch + (hash >> 2));
	}
	return hash;
}
class BloomFilter
{
public:
	BloomFilter(size_t size)
		:_capacity(size)
		, map(size)
	{}
	void Set(const string &key)
	{
		size_t index1 = BKDRHash(key.c_str())%_capacity;
		size_t index2 = SDBMHash(key.c_str()) % _capacity;
		size_t index3 = RSHash(key.c_str()) % _capacity;
		size_t index4 = APHash(key.c_str()) % _capacity;
		size_t index5 = JSHash(key.c_str()) % _capacity;
		map.Set(index1);
		map.Set(index2);
		map.Set(index3);
		map.Set(index4);
		map.Set(index5);
	}
	bool Touch(const string &key)
	{
		if (!map.Touch(BKDRHash(key.c_str()) % _capacity))
			return false;
		if (!map.Touch(SDBMHash(key.c_str()) % _capacity))
			return false;
		if (!map.Touch(RSHash(key.c_str()) % _capacity))
			return false;
		if (!map.Touch(APHash(key.c_str()) % _capacity))
			return false;
		if (!map.Touch(JSHash(key.c_str()) % _capacity))
			return false;
		return true;
	}
protected:
	size_t _capacity;
	BitMap map;
};

如有疑问希望提出,有错误希望指正

时间: 2024-10-25 03:16:55

【干货】位图的实现与布隆过滤器的相关文章

位图与布隆过滤器

给40亿个不重复的无符号整数,没排过序.给一个无符号整数,如何快速判断一个数是否在这40亿个数中.这个问题怎么解决呢? [位图方法]: 位图(BitMap) 是用一个数组中的每个数据的每个二进制位表示一个数是否存在.1表示存在,0表示不存在. 相当于把数组分成很多块的空间,每一块是32个比特位. 原来32个比特位放一个数据,现在一个位就可以放一个数据.16GB/32=0.5GB=512MB. #ifndef __BITMAP_H__#define __BITMAP_H__#include<ios

位图&布隆过滤器

位图定义: 利用位的状态来存放一个数是否存在,其实就是把一个数映射成一个简单的数用以标记他是否存在,一般使用情况为查找一个数是否存在. 数据结构: 1/8=0    1%8=1   1<<1(第二个bit位置1) 2/8=0    2%8=2   1<<2(第3个bit位置1) 3/8=0    3%8=3  1<<3(第4个bit位置1) 4/8=0    .... 查找这个数是否存在: 先算出这个数的存在位置,然后找这个位置是否为1,如果是则存在否则不存在. 缺点:

hbase中的位图索引--布隆过滤器

在hbase中,读业务是非常频繁的.很多操作都是客户端根据meta表定位到具体的regionserver然后再查询region中的具体的数据. 但是现在问题来了,一个region由一个memstore以及多个filestore组成,memstore类似缓存在服务器内存中,可以提高插入的效率,当memstore达到一定大小(由hbase.hregion.memstore.flush.size设置)或者说用户手动flush之后,就会固化存储在hdfs之类的磁盘系统上.也就是说一个region可以对应

【数据结构】位图BitMap、布隆过滤器的算法实现

我们先给出之前我看过的腾讯公司的一道笔试题,引出位图BitMap. 给40亿个不重复的无符号整数,没排过序.给一个无符号整数,如何快速判断一个数是否在这40亿个数中. 这个问题怎么解决呢? 1)将40亿数据保存起来(保存在数组.链表.树中),再和该数判断是否相等. 那我们思考一下需要多少内存: 2)借助位图BitMap解决. 位图(BitMap) 是用一个数组中的每个数据的每个二进制位表示一个数是否存在.1表示存在,0表示不存在. 相当于把数组分成很多块的空间,每一块是32个比特位. 原来32个

位图与布隆过滤器简明介绍

一个由1亿个数组成的集合M,数的范围从1~10亿 新来一个数n,如何快速且省内存地判断是否存在M中? 方法一: 将集合M的数用散列表保存,然后对数n判断是否在散列表中即可 消耗内存:假设一个数用4字节保存,1亿个数至少要381M内存,不过由于实际上由于有装载因子,散列冲突解决等,实际内存远远不止381M 方法二: 申请一个大小为10亿,数据类型为布尔的"特殊"散列表,将这一亿个数作为散列表下标,将值设成True 不过很多语言的布尔大小是1字节,并不能节省很大空间,实际上只需要使用1个二

位图应用之布隆过滤器

布隆(Burton Howard Bloom)在1970年提出的.它实际上是由一个很长的二进制向量和一系列随机映射函数组成,布隆过滤器可以用于检索一个元素是否在一个集合中.它的优点是空间效率和查询时间都远远超过一般的算法,缺点是有一定的误识别率 ... bbs.chinaacc.com/forum-2-3/topic-5672277.html bbs.chinaacc.com/forum-2-3/topic-5672278.html bbs.chinaacc.com/forum-2-3/topi

布隆过滤器的简易实现

布隆过滤器(Bloom Filter): 是由布隆(Burton Howard Bloom)提出的.它实际上是由一个很长的二进制向量和一系列随机映射函数组成,布隆过滤器用于检索一个元素是否在一个集合中.底层是利用哈希表来实现的,它可以通过一个Hash函数将一个元素映射成一个位阵列(Bit Array)中的一个点.这样一来,我们只要看看这个点是不是 1 就知道可以集合中有没有它了.这就是布隆过滤器的基本思想. 优点:空间效率和查询时间相比于其他数据结构有很大的优势 缺点:有一定的误识别率,删除困难

剖析布隆过滤器

布隆过滤器(Bloom Filter)是由布隆(Burton Howard Bloom)在1970年提出的.它实际上是由一个很长的二进制向量和一系列随机映射函数组成,布隆过滤器可以用于检索一个元素是否在一个集合中.它的优点是空间效率和查询时间都远远超过一般的算法,缺点是有一定的误识别率(假正例False positives,即Bloom Filter报告某一元素存在于某集合中,但是实际上该元素并不在集合中)和删除困难,但是没有识别错误的情形(即假反例False negatives,如果某个元素确

海量数据处理利器之布隆过滤器

看见了海量数据去重,找到停留时间最长的IP等问题,有博友提到了Bloom Filter,我就查了查,不过首先想到的是大叔,下面就先看看大叔的风采. 一.布隆过滤器概念引入 (Bloom Filter)是由布隆(Burton Howard Bloom)在1970年提出的.它实际上是由一个很长的二进制向量和一系列随机映射函数组成,布隆过滤器可以用于检索一个元素是否在一个集合中.它的优点是空间效率和查询时间都远远超过一般的算法,缺点是有一定的误识别率(假正例False positives,即Bloom