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

来源:互联网 发布:2345好压mac版 编辑:程序博客网 时间:2024/05/20 23:03

    位图是用一个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;};

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

本文出自 “pawnsir的IT之路” 博客,请务必保留此出处http://10743407.blog.51cto.com/10733407/1773175

0 0
原创粉丝点击