如何检查最近N次调用中是否使用过uint64_t值并限制存储量
针对最近N次调用值的近似检查方案
近似场景首选:布隆过滤器
这完全匹配你“近似检查”的需求,不用维护精确的历史记录,内存占用还极小:
- 工作方式:用多个哈希函数把
uint64_t值映射到位数组的不同位,检查时只要对应位全为1就认为曾出现过;当调用次数超过N时,可以直接重置整个过滤器,或者用支持滑动窗口的滚动布隆过滤器来逐步淘汰旧数据。 - 优势:插入和查询速度极快,内存开销远低于精确结构;唯一的小问题是存在可控的误判率(通过调整哈希函数数量和位数组大小就能降低),完全符合你对“近似”的要求。
精确检查的实现:队列+哈希集合
如果偶尔需要精确结果,自己结合std::queue和std::unordered_set是最直接的方式:
- 每次调用函数时的步骤:
- 先查
unordered_set里有没有当前值,拿到结果。 - 把当前值插入集合,同时塞进队列。
- 要是队列长度超过N,就弹出队首元素,并且从集合里删掉它。
- 先查
- 注意:如果同一个值被多次传入,上面的逻辑会出错(比如提前删掉还在窗口内的重复值),可以换成
std::unordered_map<uint64_t, int>记录每个值的出现次数,弹出队首时递减计数,计数归0再从map里移除。
现成封装选项
一些C++第三方库(比如Abseil、Boost)有封装好的滑动窗口式缓存/集合:
- 比如用Abseil的
absl::flat_hash_set配合滑动窗口逻辑,或者Boost的boost::circular_buffer搭配哈希集合,但本质还是队列+哈希的思路包装,要是不想引入第三方库,自己写轻量版反而更省心。
另一种近似方案:环形缓冲区+哈希
用固定大小的环形缓冲区(比如std::array或者boost::circular_buffer)存最近N个值,同步维护一个unordered_set:
- 缓冲区满时覆盖最旧的值,同时从集合里删掉被覆盖的旧值,插入新值。
- 这和队列方案逻辑类似,但内存布局更紧凑,适合N固定的场景。
内容的提问来源于stack exchange,提问作者Ahmed
相关产品推荐
相关产品推荐

