哈希函数:
常见的功能就是 打乱分布 均匀随机 输入无穷大 输出却在一定范围内
即使出现碰撞 但是每个输出对应的输入个数 概率均匀分布 没有太大偏向
一个重要的性质: 如果在input域上均匀分布 那么经过哈希并%m 运算后(在0~m-1范围内) 在输出域上同样均匀分布
哈希表:
经典结构:
根据key算出具体的hashcode值(h)----决定了value的存放位置
若 h 位置处为空 则直接将key1-value1 放入
若h位置处不为空 检查是否已有key1 若已有 则更新其对应value值 否则 直接按照链表格式,节点连在上一节点后面
经典应用:
场景题: 如果现在有一个超级大的文件,需要统计其中重复的字符串 ,我们要怎么办?
目前已知的: 可以供给1000台计算机 读取细节不用关心 只需要设计大概系统
思路 :哈希的分流特性
具体操作: 将大文件读取很多行 每一行都计算哈希值 并模1000 则这些字符串均匀分布在0-999范围内
给电脑编号0-999 对应分布在一个范围内的一些字符串用同一台电脑进行处理 达到大数据分流的效果(类似于分布式)
每台电脑只统计自己处理的重复字符串 最后将结果进行汇总即可
总结:
大数据相关的问题 有一半都是借助于哈希来解决 因为哈希具有“相同的肯定相同 不同的均匀分布”特性
在桶不够用时可以进行扩容 代价也还可以接受 一般是O(lognN)
设计一个RandomPool结构:
思路:
因为 getRandom()函数要求等概率随机返回结构中的任意一个key
所以 一张哈希表在小样本情况下无法做到随机 需要至少两张哈希表
举例:
现在有26个字符串
分别按照顺序放入两个表中 两个表的key value 是对应的
用size统计此时表中数据个数 最后getRandom()时候直接 Math.random()*26 来获取map2中对应key的value
部分代码:
解决难点: 删除过程中会在原有随机结构中出现好多洞 导致随机性变差 如何解决此问题?
思路:
z最终的总代码: