给 40亿个 不重复的无符号整数, 没排过序. 给一个无符号整数, 如何快速判断 一个数是否在这40亿个数中存在.
1 位图: 就是用每一位来存放某种状态, 适用于海量数据, 数据无重复的场景. 通常是用来 判断某个数据存不存在.
(1) 创建 byte 类型的数组, 由于是海量数据, 40亿*1bit 占用的内存不大, 可以在内存中运行.
(2) 原来的每个数通过 先除8后余8的方式, 找到具体的位置, 把该位置置为1.
(3) 判断一个数, 先通过除8后余8找到在位图中的位置, 然后看该位置的值 为1就是存在, 为0就是不存在.
位图的应用.
(1) 给定100亿 个整数, 找出只出现了一次的整数.
(1) 设计 两个位图, 同上. 如果一个数 第一次出现了, 就把 b相应的位置设为1.
(2) 如果一个数 第二次出现了, 就把 a相应的位置设为1.
(3) 0 0 表示一个数 没有出现过. 1 1 分别表示一个数 出现了2次或以上.
(4) 0 1表示一个数只出现了一次. (也可以把代码设计成 1 0 的情况).
(2) 两个文件 分别有100亿个整数, 我们只有1G 内存, 如何找到两者交集.
1 1 情况即为两者的交集 (既在a中出现, 也在b中出现).
2 布隆过滤器: 可以用来判断某个数据存不存在, 是哈希表和位图的结合. (提高查询效率, 节省大量的内存空间)
通过设计 多个哈希函数, 然后计算. A和B在集合中(所有位置的值都置为1), C和D不在集合中(只要有一个位置的为0就是不存在).
存在极小概率的 假阳性: D通过计算所有位置的值都为1, 被误判在集合中, 可以通过 增加哈希函数 的个数减少假阳性的概率.
3 海量数据找到出现次数最多的元素. 5TB的访问日志, 找到出现次数最多的 ip.
(1) 按照哈希分组, 然后统计 每组出现次数最多的元素, 然后进行比较.
(2) 进行比较. 关键在于 哈希函数的设计.
4 海量数据 + topk问题. 5TB的访问日志, 找到出现次数 最多的10个ip.
(1) 按照哈希分组, 并统计出 每个组每个ip出现的次数.
(2) 每个组分别用 优先级队列建立 最小堆(堆中存储10个元素), 找出 该组 出现次数最多的10个元素.
(3) 取出并比较这些组的元素, 找到 top10 的ip.