目录
一、位图
1.1 概念
1.2 应用
1.3 模拟实现
1.31 把比特位上的值设置为1
1.32 把比特位上的值设置为0
1.33 检测比特位上的值是否是1
1.34 代码
二、布隆过滤器
2.1 概念
2.2 优点
2.3 缺点
2.4模拟实现
一、位图
1.1 概念
运用哈希的思想,将整型映射到比特位上,比特位上的值为0就是不存在,1就是存在。这样就能达到检测一组不重复的数据是否出现在已有的数据中了。
重点:数据不能重复
1.2 应用
用于门禁,指纹密码等。
1.3 模拟实现
1.31 把比特位上的值设置为1
a为0或者1,当1 | a=1,通过按位或的特性,把比特位上的值设置为1.
下图是1先左移pos位,才能和pos对齐,再进行按位或运算。
1.32 把比特位上的值设置为0
a为0或1,0&a=0,1&a=a;所以在需要设置的位&0,其他位&1,就能保证只有这个需要改变的bit位设置为0,不造成对其他数据的影响。这种数怎么得到呢?
通过对1左移pos位,再按位取反,就能得到想要的值了。
1.33 检测比特位上的值是否是1
先找到数据所在的比特位和下标
把bit位所在的下标的int值取出,然后再右移pos位,&1。如果是1就说明存在,0就是不存在。
1.34 代码
#pragma once
#include <iostream>
using namespace std;
#include <vector>class bitset{public:bitset(size_t bitCount): _bit((bitCount >> 5) + 1), _bitCount(bitCount){}// 将which比特位置1void set(size_t which){if (which > _bitCount){return;}size_t index = which >> 5;//一次处理,得到vector的下标size_t pos = which % 32; //二次处理,取得具体的bit位_bit[index] |= (1 << pos);}// 将which比特位置0void reset(size_t which){if (which > _bitCount){return;}size_t index = which >> 5;size_t pos = which % 32;_bit[index] &= ~(1 << pos);}// 检测位图中which是否为1bool test(size_t which){if (which > _bitCount){return false;}size_t index = which >> 5;size_t pos = which % 32;return (_bit[index] >> pos) & 1;}size_t size()const { return _bitCount; }private:vector<int> _bit;size_t _bitCount;};
二、布隆过滤器
2.1 概念
高效地插入和查询,可以告诉你,某种东西一定不存在或者可能存在,用多个哈希函数,将一个数据映射到位图中,不仅可以提升查询效率,而且很大节省空间。
a.用于处理string类的数据,结合位图,一个string对应多个哈希函数
b.存在的值,不会判定为不存在,如果判定不存在,则一定不存在。不存在的值,可能会发生哈希冲突,判定为存在。
下图为一个string用5个哈希函数的值映射的比特位来确定。设置这5个比特位都为1,检测时需要5个比特位都为1才表示存在。
2.2 优点
1.不存储元素本身
2.承受一定误判时,比其他数据结构有更大空间优势
3.数据量很大时,可以表示全集
4.可以进行交、并、差运算
2.3 缺点
1.不能准确判断元素是否在集合中,有误判率
2.不能获取元素本身
3.一般情况下不能从布隆过滤器中删除元素,会影响其他元素的存在状态
2.4模拟实现
5个哈希函数就没放上来了。
template<class K=string, class KToInt1 = KeyToInt1, class KToInt2 = KeyToInt2,class KToInt3 = KeyToInt3, class KToInt4 = KeyToInt4,class KToInt5 = KeyToInt5>
class BloomFilter
{
public:BloomFilter(size_t size) // 布隆过滤器中元素个数: _bmp(5 * size), _size(0){}// 插入数据bool Insert(const K& key){size_t len = _bmp.size();size_t index1 = KToInt1()(key)%len;size_t index2 = KToInt2()(key)%len;size_t index3 = KToInt3()(key)%len;size_t index4 = KToInt4()(key)%len;size_t index5 = KToInt5()(key)%len;_bmp.set(index1);_bmp.set(index2);_bmp.set(index3);_bmp.set(index4);_bmp.set(index5);_size++;return true;}// 检测在不在bool IsInBloomFilter(const K& key){int len = _bmp.size();int index1 = KToInt1()(key) % len;if (_bmp.test(index1) == false){return false;}int index2 = KToInt2()(key) % len;if (_bmp.test(index2) == false){return false;}int index3 = KToInt3()(key) % len;if (_bmp.test(index3) == false){return false;}int index4 = KToInt4()(key) % len;if (_bmp.test(index4) == false){return false;}int index5 = KToInt5()(key) % len;if (_bmp.test(index5) == false){return false;}return true;}
private:bitset<100> _bmp;size_t _size; // 实际元素的个数
};