数据结构 布隆过滤器

头文件

cpp 复制代码
#include <stdint.h>
#include <stddef.h>

// 布隆过滤器结构
typedef struct BloomFilter {
    uint8_t* bit_array;      // 位数组
    size_t bit_array_size;   // 位数组大小(字节数)
    size_t num_bits;         // 总位数
    int num_hash_funcs;      // 哈希函数数量
    size_t element_count;    // 已插入元素数量
} BloomFilter;

// API 函数
// 创建布隆过滤器
BloomFilter* bloom_filter_create(size_t num_bits, int num_hash_funcs);
//销毁
void bloom_filter_destroy(BloomFilter* filter);
//添加元素
int bloom_filter_add(BloomFilter* filter, const char* element);
//检查元素是否存在
int bloom_filter_contains(const BloomFilter* filter, const char* element);
//获得已插入元素数量
size_t bloom_filter_size(const BloomFilter* filter);
//清空
void bloom_filter_clear(BloomFilter* filter);
//计算理论误判率
double bloom_filter_false_positive_rate(const BloomFilter* filter);

源文件

cpp 复制代码
#include "布隆过滤器.h"
#include <stdlib.h>
#include <string.h>
#include <math.h>

// 哈希函数1:DJB2
static uint32_t hash1(const char* str) {
    uint32_t hash = 5381;
    int c;
    while ((c = *str++)) {
        hash = ((hash << 5) + hash) + c; // hash * 33 + c
    }
    return hash;
}

// 哈希函数2:FNV-1a
static uint32_t hash2(const char* str) {
    uint32_t hash = 2166136261u;
    while (*str) {
        hash ^= (uint8_t)(*str);
        hash *= 16777619u;
        str++;
    }
    return hash;
}
// 双哈希法生成第i个哈希值
static uint32_t get_hash(const BloomFilter* filter, const char* str, int i) {
    uint32_t h1 = hash1(str);
    uint32_t h2 = hash2(str);
    return (h1 + i * h2) % filter->num_bits;
}
// 创建布隆过滤器
BloomFilter* bloom_filter_create(size_t num_bits, int num_hash_funcs) {
    if (num_bits == 0 || num_hash_funcs <= 0) {
        return NULL;
    }
    BloomFilter* filter = (BloomFilter*)malloc(sizeof(BloomFilter));
    if (!filter) return NULL;
    // 计算需要的字节数(向上取整)
    size_t byte_size = (num_bits + 7) / 8;
    filter->bit_array = (uint8_t*)calloc(byte_size, sizeof(uint8_t));
    if (!filter->bit_array) {
        free(filter);
        return NULL;
    }
    filter->bit_array_size = byte_size;
    filter->num_bits = num_bits;
    filter->num_hash_funcs = num_hash_funcs;
    filter->element_count = 0;
    return filter;
}

// 销毁布隆过滤器
void bloom_filter_destroy(BloomFilter* filter) {
    if (filter) {
        if (filter->bit_array) {
            free(filter->bit_array);
        }
        free(filter);
    }
}

// 添加元素
int bloom_filter_add(BloomFilter* filter, const char* element) {
    if (!filter || !element) return 0;
    size_t len = strlen(element);
    if (len == 0) return 0;
    for (int i = 0; i < filter->num_hash_funcs; i++) {
        uint32_t hash = get_hash(filter, element, i);
        size_t byte_index = hash / 8;
        uint8_t bit_offset = hash % 8;
        // 设置位
        filter->bit_array[byte_index] |= (1 << bit_offset);
    }
    filter->element_count++;
    return 1;
}

// 检查元素是否存在
int bloom_filter_contains(const BloomFilter* filter, const char* element) {
    if (!filter || !element) return 0;
    size_t len = strlen(element);
    if (len == 0) return 0;
    for (int i = 0; i < filter->num_hash_funcs; i++) {
        uint32_t hash = get_hash(filter, element, i);
        size_t byte_index = hash / 8;
        uint8_t bit_offset = hash % 8;
        // 检查位是否被设置
        if (!(filter->bit_array[byte_index] & (1 << bit_offset))) {
            return 0; // 肯定不存在
        }
    }
    return 1; // 可能存在(可能误判)
}

// 获取已插入元素数量
size_t bloom_filter_size(const BloomFilter* filter) {
    return filter ? filter->element_count : 0;
}

// 清空布隆过滤器
void bloom_filter_clear(BloomFilter* filter) {
    if (filter && filter->bit_array) {
        memset(filter->bit_array, 0, filter->bit_array_size);
        filter->element_count = 0;
    }
}

// 计算理论误判率
double bloom_filter_false_positive_rate(const BloomFilter* filter) {
    if (!filter || filter->element_count == 0) return 0.0;
    // 误判率公式: (1 - e^(-k * n / m))^k
    double k = filter->num_hash_funcs;
    double m = filter->num_bits;
    double n = filter->element_count;
    double exponent = -k * n / m;
    return pow(1 - exp(exponent), k);
}
相关推荐
qeen872 小时前
【数据结构】建堆的时间复杂度讨论与TOP-K问题
c语言·数据结构·c++·学习·
图码2 小时前
如何用多种方法判断字符串是否为回文?
开发语言·数据结构·c++·算法·阿里云·线性回归·数字雕刻
我星期八休息3 小时前
IT疑难杂症诊疗室:AI时代工程师Superpowers进化论
linux·开发语言·数据结构·人工智能·python·散列表
漂流瓶jz3 小时前
UVA-1152 和为0的4个值 题解答案代码 算法竞赛入门经典第二版
数据结构·算法·二分查找·题解·aoapc·算法竞赛入门经典·uva
你撅嘴真丑3 小时前
map 与 set容器的应用--话题焦点人物
数据结构
生成论实验室3 小时前
《事件关系阴阳博弈动力学:识势应势之道》第二篇:阴阳博弈——认知的动力学基础
数据结构·人工智能·科技·神经网络·算法
li1670902704 小时前
第二十七章:智能指针
c语言·数据结构·c++·visual studio
代码中介商6 小时前
数据结构开篇:从问题到解决方案
数据结构
AKDreamer_HeXY7 小时前
QOJ 12255 - 36 Puzzle 题解
数据结构·c++·数学·算法·icpc·qoj
Rabitebla7 小时前
vector 的骨架:三根指针、模板陷阱与迭代器失效的第一现场
开发语言·数据结构·c++·算法