海量数据去重

set和map

  • c++标准库(STL)中的set和map结构都是采用红黑树实现的,它增删改查的时间复杂度是 O ( l o g 2 n ) ) O(log{_{2}}^{n})) O(log2n))
  • 图结构实例:
    在这里插入图片描述
  • 对于严格平衡二叉搜索树,100w条数据组成的红黑树,只需要比较20次就能找到该值;对于10亿
    条数据只需要比较30次就能找到该数据;也就是查找次数跟树的高度是一致的
  • 对于红黑树来说平衡的是黑节点高度,所以研究比较次数需要考虑树的高度差,最好情况某条树链
    路全是黑节点,假设此时高度为h1,最差情况某条树链路全是黑红节点间隔,那么此时树高度为
    2*h1
  • 在红黑树中每一个节点都存储key和val字段,key是用来做比较的字段;红黑树并没有要求key字段
    唯一,在set和map实现过程中限制了key字段唯一。
  • 另外set和map的关键区别是set不存储val字段;
  • 优点:存储效率高,访问速度高效;
  • 缺点:对于数据量大且查询字符串比较大且查询字符串相似时将会是噩梦;

1、找到待插入节点的位置
2、(重新着色平衡等)
在这里插入图片描述
在这里插入图片描述
所以可以插入红黑树可以插入相同的节点
在这里插入图片描述
如果不插入相同节点,则判断相等时改为赋值

set 和 map 的关键区别是set不存储val字段
优点:存储效率高(没浪费空间),访问效率高
缺点:对于数据量大且查询字符串相似时将会是噩梦

unorder_map

由哈希表实现,数组+哈希函数
将字符串通过哈希函数生成一个整数在银蛇到数组当中,增删改查时间复杂度O(1)
在这里插入图片描述
哈希函数的作用:避免插入的时候字符串的比较;能随机分布在数组之中
哈希函数一般返回64位整数,将多个大数映射到一个小数组中,必然会产生冲突
如何选择哈希函数:
1、计算速度快
2、哈希相似字符串能保持蔷随即分布性(防碰撞)

负载因子:数组存储元素的个数/数组长度,负载因子越小,冲突越小,负载因子越大,冲突越大。

哈希冲突解决方案:
1、链表法:
将冲突元素使用链表链接起来。如果冲突的链表过长,可以换成红黑树(java8);又原来链表时间复杂度O(n),改为 l o g 2 n log{_{2}}^{n} log2n。一般可以采用超过256个节点改为红黑树。

2、开放寻址法
将所有元素放在哈希表中,不使用额外的数据结构,一般使用线性探查法的思路解决:
(1)当插入新元素时,使用哈希函数在哈希表中定位元素位置,
(2)检查数组中该槽位索引是否存在元素,如果为空则插入,否则(3),
(3)加上一定步长接着检查(2)
步长一般如下:
在这里插入图片描述
这两种都会导致同类哈希聚集,也就是近似值它的哈希只也相近,数组槽位也相近,形成哈希聚集。
另外还可以使用双重哈希来解决上面出现的哈希聚集现象。
在这里插入图片描述
具体原理
简化为hash1 + k * hash2

同样的,hashtable节点中存储val和key,不要求key大小顺序

优点:访问速度更快,不需要进行字符串比较
缺点:需要引⼊策略避免冲突,存储效率不高;空间换时间;

map set unorder_map都不能解决上诉问题?需要存储string,海量数据,我们没有这么多内存

布隆过滤器
布隆过滤器是一种概率型数据结构,它的特点是有效的插入和查询,能明确告知某个字符串一定不存在或者可能存在
优点:布隆过滤器相比传统的查询结构(例如: hash, set, map等数据结构)更加高效,占用空间更小;
缺点:它返回的结果是概率性的,也就是说结果存在误差的,虽然这个误差是可控的;同时它不支持删除操作;
组成:位图+n个hash函数

在这里插入图片描述

不支持的删除的原因是因为不知道是哪个str把这位设置为1(如下)
在这里插入图片描述
实际应用
在这里插入图片描述
n、p自己设置,算出m、k

n越大p越大
m越大p越小
但是对于k有一个最佳值使得p最小

在这里插入图片描述
类似于双重hash,避免在k个函数之中冲突。
并不是真的有k个hash函数,而是使用hash1和hash2算出k个hash

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值