用C/C++实现针对整数的BoomFilter
整数布隆过滤器 (Bloom Filter for Integers) 实现
布隆过滤器是一种空间效率高的概率型数据结构,用于判断一个元素是否在集合中。下面是一个针对整数的布隆过滤器C++实现:
#include <iostream>
#include <vector>
#include <bitset>
#include <functional>
class IntegerBloomFilter {
private:
std::vector<bool> bit_array; // 位数组
int size; // 位数组大小
int num_hashes; // 哈希函数数量
// 哈希函数1
size_t hash1(int key) const {
std::hash<int> hasher;
return hasher(key) % size;
}
// 哈希函数2
size_t hash2(int key) const {
// 使用另一个简单的哈希算法
key = ((key >> 16) ^ key) * 0x45d9f3b;
key = ((key >> 16) ^ key) * 0x45d9f3b;
key = (key >> 16) ^ key;
return key % size;
}
public:
// 构造函数
IntegerBloomFilter(int size, int num_hashes) : size(size), num_hashes(num_hashes) {
bit_array.resize(size, false);
}
// 添加元素
void add(int key) {
size_t h1 = hash1(key);
size_t h2 = hash2(key);
for (int i = 0; i < num_hashes; ++i) {
size_t combined_hash = (h1 + i * h2) % size;
bit_array[combined_hash] = true;
}
}
// 检查元素是否存在(可能有误判)
bool contains(int key) const {
size_t h1 = hash1(key);
size_t h2 = hash2(key);
for (int i = 0; i < num_hashes; ++i) {
size_t combined_hash = (h1 + i * h2) % size;
if (!bit_array[combined_hash]) {
return false;
}
}
return true;
}
// 清空布隆过滤器
void clear() {
std::fill(bit_array.begin(), bit_array.end(), false);
}
// 获取位数组大小
int getSize() const {
return size;
}
// 获取哈希函数数量
int getNumHashes() const {
return num_hashes;
}
};
int main() {
// 创建一个布隆过滤器,位数组大小为1000,使用5个哈希函数
IntegerBloomFilter bloomFilter(1000, 5);
// 添加一些整数
bloomFilter.add(42);
bloomFilter.add(1337);
bloomFilter.add(123456);
bloomFilter.add(-99); // 支持负整数
// 测试存在性
std::cout << "Contains 42: " << bloomFilter.contains(42) << std::endl; // 应该输出1 (true)
std::cout << "Contains 1337: " << bloomFilter.contains(1337) << std::endl; // 应该输出1 (true)
std::cout << "Contains 999: " << bloomFilter.contains(999) << std::endl; // 可能输出0 (false)
// 测试误判率
int false_positives = 0;
int tests = 10000;
for (int i = 2000; i < 2000 + tests; ++i) {
if (bloomFilter.contains(i)) {
false_positives++;
}
}
std::cout << "False positive rate: " << (false_positives * 100.0 / tests) << "%" << std::endl;
return 0;
}
实现说明
-
数据结构:使用
vector<bool>
作为位数组,这是C++中高效存储位的方式。 -
哈希函数:
- 使用两个基础哈希函数:
hash1
使用C++标准库的std::hash
,hash2
使用一个简单的乘法哈希 - 通过线性组合这两个哈希函数生成多个不同的哈希值
- 使用两个基础哈希函数:
-
操作:
add(int key)
:将整数添加到布隆过滤器中contains(int key)
:检查整数是否可能在集合中(可能有假阳性)clear()
:重置布隆过滤器
-
参数选择:
- 位数组大小(
size
)和哈希函数数量(num_hashes
)影响误判率 - 通常根据预期元素数量和可接受的误判率来选择这些参数
- 位数组大小(
使用建议
- 布隆过滤器适用于可以容忍一定误判率的场景
- 不支持删除操作(标准布隆过滤器)
- 对于整数类型,可以专门优化哈希函数以获得更好性能
如果需要支持删除操作,可以考虑使用计数布隆过滤器(Counting Bloom Filter)的变种。
参考
C++ 中std::bitset的使用总结
C++ 实现布隆过滤器 - 从上亿条数据中查找某个记录是否存在