概念
基于位图的缺点——只能保存整型,在现实中的应用有了很大的局限性,所以又引出了一种新的哈希变形,其实也算是位图的变形——布隆过滤器。
如图,把字符串经过布隆过滤器的处理,映射到位图的多个位置,让这几个位置都置成1用来表示这个字符串的存在。所以只要有一个位置为0,那么这个数据就不存在。
问题
1.本来不存在的数据,可能因为保存的数据过多导致误判。比如下图中的close,其实不存在,因为其他数据占用了他的空间导致误判。
2.只能保存不能删除,如果删除了string,就影响了open的保存。
代码接口实现
#pragma once
#include <stdlib.h>
#include <assert.h>
#include "BitMap.h"
typedef const char* KeyType;
typedef size_t(*HASH_FUNC)(KeyType str);
static size_t BKDRHash1(const char* str)
{
size_t hash = 0;
size_t seed = 31; //131 1313 13131 131313
while (*str)
{
hash = hash*seed + *str++;
}
return (hash & 0x7FFFFFFF);
}
static size_t BKDRHash2(const char* str)
{
size_t hash = 0;
size_t seed = 1313; //131 1313 13131 131313
while (*str)
{
hash = hash*seed + *str++;
}
return (hash & 0x7FFFFFFF);
}
static size_t BKDRHash3(const char* str)
{
size_t hash = 0;
size_t seed = 131313; //131 1313 13131 131313
while (*str)
{
hash = hash*seed + *str++;
}
return (hash & 0x7FFFFFFF);
}
typedef struct BloomFilter
{
BitMap _bm;
//size_t* _bm;
HASH_FUNC _hashfunc1;
HASH_FUNC _hashfunc2;
HASH_FUNC _hashfunc3;
}BloomFilter;
void BloomFilterInit(BloomFilter* bf, size_t range) //初始化
{
assert(bf);
BitMapInit(&bf->_bm, range);
bf->_hashfunc1 = BKDRHash1;
bf->_hashfunc2 = BKDRHash2;
bf->_hashfunc3 = BKDRHash3;
}
void BloomFilterSet(BloomFilter* bf, KeyType key) //插入
{
assert(bf);
size_t keyone = bf->_hashfunc1(key);
size_t keytwo = bf->_hashfunc2(key);
size_t keythree = bf->_hashfunc3(key);
size_t range = bf->_bm._range;
BitMapSet(&bf->_bm, keyone%range);
BitMapSet(&bf->_bm, keytwo%range);
BitMapSet(&bf->_bm, keythree%range);
}
int BloomFilterTest(BloomFilter* bf, KeyType key) //判断是否存在
{
assert(bf);
size_t keyone = bf->_hashfunc1(key);
size_t keytwo = bf->_hashfunc2(key);
size_t keythree = bf->_hashfunc3(key);
size_t range = bf->_bm._range;
if (BitMapTest(&bf->_bm, keyone%range) == -1)
return -1;
if (BitMapTest(&bf->_bm, keytwo%range) == -1)
return -1;
if (BitMapTest(&bf->_bm, keythree%range) == -1)
return -1;
return 0;
}
void BloomFilterReset(BloomFilter* bf, KeyType key) //删除
{
assert(bf);
}
void BloomFilterDestory(BloomFilter* bf) //销毁
{
assert(bf);
BitMapDestory(&bf->_bm);
bf->_hashfunc1 = NULL;
bf->_hashfunc2 = NULL;
bf->_hashfunc3 = NULL;
}