位图与布隆过滤器 的说明 介绍
来源:互联网 发布:阿里巴巴服装淘宝网 编辑:程序博客网 时间:2024/05/18 02:46
在平常的编程中 ,我们经常要有一些判断,某个数据 ,,在不在一个文件或者什么中 ???、
如果 是 以前 我们 ,没有 学习 数据 结构 之前,,,我们 一看到这种题目 ,,,我们所能 想到的第一种 方法;就是 使用 二分查找 ,,,但是 这种方法 有限制 成,,,必须是 有序的数据 ,,,,才可使用 这种方法 。。。。
但是 ,,,,在学习数据 结构 之后,我们 就有很多 的 方法来 解决这种 问题 了 。。。。
就比如 ,,,,说我们 可使用 搜索二叉树来 查找数据 ,也可是使用 红黑树来查找 ,,,
算法的时间复杂度都是O(log2 N);;;
那么今天我们就来说一说 同样应用于搜索的两类结构;;;;
1、位图
之前,,,某个公司的面试 出了这么一道题 ;;;;
有40亿个无符号整型的值,,,,我们要早其中找到某个整型 是否存在 ????假设我们的运行内存为 1G。。。
当遇到这种问题的时候 ,,我们就不能 使用上述的方法来实现了 。。。。
为什么呢???
40亿个 unsigned int 在内存中的容量大致计算得到的 是 大约 16G的内存 ;;;
如果要是使用上面的二叉树来查找的话、、、、、
那么,,,建立的树的大小,,,,远远大于运行 内存 ,,,,,根本无法实现 。。。。
所以,,,在这里我们 引入了一个新的结构————位图————————;
对于上面说说的那类题型 ,, ,我们要了解到,,我们 所要知道的仅仅是 ,,,,某个数在不在 ,,,,一个集合中 。。。。
所以,,对于这类数据 ,,,,我们 只需要两种 状态来 ,,标记 这些 。。。
所以,,我们 可以使用 一个bit为来表示 这俩种 状态 1或者是 0;;
这种方法就是 我们所说的位图 。。。。。
所以 ,,,对于 位图 的,,结构 ,我们可以只是 使用一个 vector内部存放的数据类型 为size_t ,
也就是 说 一个元素可以表示 8个数据的存在与否 ;;;;
图形结构 显示:::
其中 0表示 ,,,不存在,1表示 存在 ,,
如果要是 使用的是 这种方法的话 ,,,,那么所有的整型值,,,所有建立的vector容器的大小才500M
并且,,,查找的时间复杂度大致相当于O(1);
代码实现
#pragma once#include<vector>class BitMap{public:BitMap(const size_t & n)//n内部表示数据的个数 {_bt.resize((n>>5)+1);//开辟空间}void Set(const size_t value)//设置内部值{size_t idex = value>>5;//找到该数存储在那个整型的范围内size_t num = value %32; //找到在整形的哪个位上_bt[idex] |= (1<<num);//将这位置设置成 1;}void ReSet(const size_t value)//重置{size_t idex =value>>5;size_t num =value%32;_bt[idex] &= ~(1<<num);//将位置设置 成 0 ;}bool Test(const size_t value){size_t idex = value>>5;size_t num = value%32;if(_bt[idex] & (1<<num))//如果位置上的量是 1 return true;//表示 存在return false;//表示 不存在}protected:vector<size_t> _bt;};void TestBitMap(){BitMap bt((size_t ) -1);bt.Set(1);bt.Set(10432);bt.Set(1034);bt.Set(320);cout<<"1 ?"<<bt.Test(1)<<endl;cout<<"10432 ?"<<bt.Test(10432)<<endl;cout<<"1034 ?"<<bt.Test(1034)<<endl;cout<<"321 ?"<<bt.Test(321)<<endl;bt.ReSet(1034);cout<<"1034 ?"<<bt.Test(1034)<<endl;}
位图的使用大致就是 这个样子了 。。。。。、
但是,我们在平常的编程中 是用的大部分都是 字符串 ,,,,,但是这里有不能来处理 ,,,,,
所以 ,,就要引入我们的新的结构-------布隆过滤器
布隆过滤器
在平常的生活中我们经常要来判断,,一个元素是否在一个集合中,,,;;;;
就好像是,我们要早电话本中查看是否有某人的号码,,,,还有就是 检查一个英文单词的拼写是不是很正确。。
我们经常会想到是,使用的是哈希表,,,,这种数据结构的主要优点就是 :::快速准确,,但又很浪费空间 。。。如果要是,,查找的数据量十分的庞大的话 ,,哈希表的存储效率就会大大的下降 。。。。
如果要是使用的是位图的话,,就可以将这个解决,,但是位图,,无法用来表示 字符串。。。
所以我们 就引入了布隆过滤器这个东西。。。。。
所谓的布隆就是将位图 的特点与哈希表来结合起来 ,,,
但是 ,,,,哈希表有 哈希冲突 ;;
所以 ,,我们 就可以使用 5个位来表示这个字符串,,,,,所以这里就要 熟悉字符串的哈希算法;;;
http://www.cnblogs.com/-clq/archive/2012/05/31/2528153.html
但是 这样。。还是会有冲突的,,,,但是 几率是 十分低的。。。
所以 说 ,,,,布隆只能拿到的是 近似值。。。
换句话说就是,,,,,
在布隆里找一个数据 ,,,,找到的话 ,,,不一定准确,,,但没找到,,一定准确
代码的实现
#pragma once #include"BitMap.h"#include"HashFunc.h"#include<string>typedef long long LongType;struct __HashFunc1{template<class T> size_t BKDRHash(const T *str) { register size_t hash = 0; while (size_t ch = (size_t)*str++) { hash = hash * 131 + ch; // 也可以乘以31、131、1313、13131、131313.. // 有人说将乘法分解为位运算及加减法可以提高效率,如将上式表达为:hash = hash << 7 + hash << 1 + hash + ch; // 但其实在Intel平台上,CPU内部对二者的处理效率都是差不多的, // 我分别进行了100亿次的上述两种运算,发现二者时间差距基本为0(如果是Debug版,分解成位运算后的耗时还要高1/3); // 在ARM这类RISC系统上没有测试过,由于ARM内部使用Booth's Algorithm来模拟32位整数乘法运算,它的效率与乘数有关: // 当乘数8-31位都为1或0时,需要1个时钟周期 // 当乘数16-31位都为1或0时,需要2个时钟周期 // 当乘数24-31位都为1或0时,需要3个时钟周期 // 否则,需要4个时钟周期 // 因此,虽然我没有实际测试,但是我依然认为二者效率上差别不大 } return hash; } size_t operator()(const string& key){return BKDRHash(key.c_str());}};struct __HashFunc2{template<class T> size_t SDBMHash(const T *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& key){return SDBMHash(key.c_str());}};struct __HashFunc3{template<class T> size_t RSHash(const T *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& key){return RSHash(key.c_str());}};struct __HashFunc4{template<class T> size_t APHash(const T *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& key){return APHash(key.c_str());}};;struct __HashFunc5{template<class T> size_t JSHash(const T *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; } size_t operator()(const string& key){return JSHash(key.c_str());}};template<class K,class HashFunc1 = __HashFunc1,class HashFunc2 = __HashFunc2,class HashFunc3 = __HashFunc3,class HashFunc4 = __HashFunc4,class HashFunc5 = __HashFunc5>class BloomFilter{public:BloomFilter(const LongType num):_size(num*10),_bt(num*10){}void Set(const K& key){size_t hash1 = HashFunc1()(key);size_t hash2 = HashFunc2()(key);size_t hash3 = HashFunc3()(key);size_t hash4 = HashFunc4()(key);size_t hash5 = HashFunc5()(key);_bt.Set(hash1);_bt.Set(hash2);_bt.Set(hash3);_bt.Set(hash4);_bt.Set(hash5);}bool Test(const K& key){size_t hash1 = HashFunc1()(key);size_t hash2 = HashFunc2()(key);size_t hash3 = HashFunc3()(key);size_t hash4 = HashFunc4()(key);size_t hash5 = HashFunc5()(key);if(_bt.Test(hash1) == false)return false;if(_bt.Test(hash2) == false)return false;if(_bt.Test(hash3) == false)return false;if(_bt.Test(hash4) == false)return false;return _bt.Test(hash5);}protected:BitMap _bt;LongType _size;};void TestBloomFilter(){BloomFilter<string> bt(-1);char * url1 = "http://www.cnblogs.com/-clq/archive/2012/05/31/2528153.html";char * url2 = "http://www.cnblogs.com/-clq/archive/2012/05/31/2528111.html";char * url3 = "http://www.cnblogs.com/-clq/archive/2012/05/31/2358111.html";char * url4 = "http://www.cnblogs.com/-clq/archive/2012/05/31/24328111.html";bt.Set(url1);bt.Set(url2);bt.Set(url3);bt.Set("xiao");bt.Set("xiao1");cout<<url1<<" "<<bt.Test(url1)<<endl;cout<<url2<<" "<<bt.Test(url2)<<endl;cout<<url3<<" "<<bt.Test(url3)<<endl;cout<<url4<<" "<<bt.Test(url4)<<endl;cout<<"xiao ?"<<" "<<bt.Test("xiao")<<endl;cout<<"xiao1 ?"<<" "<<bt.Test("xiao1")<<endl;}
0 0
- 位图与布隆过滤器 的说明 介绍
- 布隆过滤器与位图
- 布隆过滤器与位图
- 【干货】位图的实现与布隆过滤器
- 位图BitMap与布隆过滤器BloomFilter
- 位图&布隆过滤器
- 位图和布隆过滤器
- 【哈希表】+【位图】+【布隆过滤器】
- 【数据结构】位图BitMap与布隆过滤器BloomFilter
- 位图与哈希扩展:Bloom Filter(布隆过滤器)
- 【数据结构】位图BitMap、布隆过滤器的算法实现
- 布隆过滤器的简单介绍与实例(Bloom Filter)
- 过滤器:自清洗过滤器的原理与技术特点说明
- 位图(BitMap)&& 布隆过滤器(BloomFilter)
- 【数据结构】布隆过滤器——位图扩展
- 位图和布隆过滤器以及哈希切分
- DOM与JQuery选择器、过滤器的介绍
- 布隆过滤器原理介绍
- 传感器
- spring参数注入细节
- 108. Convert Sorted Array to Binary Search Tree
- 泛型以及泛型擦除
- Handler机制分析之一
- 位图与布隆过滤器 的说明 介绍
- 线段树例题5
- Stanford编程方法学公开课作业 2 ---- Karel中生成棋盘的代码
- Java提高篇---HashMap
- Autonomous RC Car
- 较简单的修改和添加功能(链接数据库)
- C primer plus---第一章:概览
- height、clientHeight、scrollHeight、offsetHeight区别
- 登录校园网