采用分桶位图法:先按高8位分256桶,每桶动态分配字节数组,再对低24位执行位操作,兼顾内存效率与稀疏性支持。

一、使用std::vector手动管理位存储
该方案规避std::vector
1、计算所需字节数:size_t byte_size = (max_value + 7) / 8;
2、分配连续内存:std::vector
3、置位操作:bits[n >> 3] |= (1
4、查位操作:return (bits[n >> 3] & (1
5、关键校验:插入前必须检查n >= 0 && n ,否则触发未定义行为。
二、分桶+局部Bitmap结构
针对稀疏大值域(如随机int范围-2³¹~2³¹−1),通过高位哈希分桶将全局映射拆解为多个局部紧凑位图,避免全量内存分配,实现按需加载与内存可控。
1、设定桶数:例如取高8位,共256个桶,桶索引 bucket = static_cast
2、为每个非空桶动态分配std::vector
3、桶内偏移计算:local_n = n & 0xFFFFFF(保留低24位);
4、在对应桶中执行位操作:buckets[bucket][local_n >> 3] |= (1
5、查询时需遍历所有可能桶,但实际只需检查对应bucket索引下的单个位图,其余桶可跳过。
三、基于std::vector的64位对齐位图
利用64位寄存器原生位指令提升吞吐,减少循环次数与缓存行访问频次,适合高性能去重场景,尤其在-O2 -march=native编译下可生成bts/bt等单周期指令。
1、计算word数量:size_t word_count = (max_value + 63) / 64;
2、分配对齐内存:使用aligned_alloc(64, word_count * sizeof(uint64_t))或posix_memalign;
3、置位:data[index / 64] |= (1ULL
4、查位:(data[index / 64] & (1ULL
5、重要提示:必须用 index % 64 替代 index & 63 以避免负数索引误算,且调试版应加入assert(index
四、两级哈希近似去重(Bloom Filter变种)
当严格精确性可适度让步于内存压缩时,采用高位定桶+低位定偏移策略构建概率可控的近似位图,将GB级内存压缩至数百MB,适用于日志ID、URL哈希等高吞吐场景。
1、第一级哈希取高12位作为桶号:bucket = (x >> 52) & 0xfff;
2、第二级哈希计算32位指纹并截断低20位:bit_pos = fast_hash(x) & 0xfffff;
3、每个桶使用std::bitset(128KB);
4、插入仅执行set(bit_pos),不检查原值;
5、查询返回true仅表示可能已存在(存在假阳性),返回false则表示绝对未见过。
五、惰性分段位图(Segmented Bitmap)
应对超大值域(如0~2³²−1)且数据分布高度不均的情况,将值域划分为固定长度段,仅在首次写入某段时分配其位图内存,显著降低峰值内存占用。
1、设定段长:SEGMENT_SIZE = 1U
2、段索引计算:segment_idx = n / SEGMENT_SIZE;
3、段内偏移:offset = n % SEGMENT_SIZE;
4、使用std::vector<:unique_ptr>>> segments管理;
5、插入前检查segments[segment_idx]是否存在,若为空则初始化为std::vector
6、关键保障:段分配必须延迟且线程安全,推荐使用std::atomic<:unique_ptr>>或CAS初始化。
C++免费学习笔记(深入):立即使用
在学习笔记中,你将探索 C++ 的入门与实战技巧!











