构建一个完美无冲突的 hashmap。

2022-04-18 17:52:16 +08:00
 3dwelcome
首先,hashmap 是把一个很长的字符串,散列成固定长度。由于原始数据是无限长,而散列值长度基本是固定的,所以无法避免 hash 冲突。

但是,我们可以通过设计一个前置过滤函数,让一个 hashmap 变成一组 hashmap.

类似砂石过滤里的多层滤网原理。

第一层是粗砂砾,也就是计算每个元素,如果 hash 函数并无冲突,就保留在第一层。其余元素自动流到第二层。
第二层是中砂砾,元素被过滤一次,数量减少了。用第二个 hash 函数来过滤,明显会减少冲突。还有冲突,就流到第三层。
第三层是细砂砾,以此类推,直到所有元素被处理完成。

这样就可以避免 hashmap 出现碰撞的情况了。当然真实场景里,并不需要一组 hashmap ,可以优化到多层 bitmap 数据+一个 hashmap 来保存和查询结果。
4917 次点击
所在节点    算法
99 条回复
wd
2022-04-18 18:02:10 +08:00
....
casparchen
2022-04-18 18:20:07 +08:00
...
blindpirate
2022-04-18 18:21:36 +08:00
......
oneisall8955
2022-04-18 18:24:33 +08:00
请问 map.get(key)怎么实现?
PureWhiteWu
2022-04-18 18:26:48 +08:00
STFC
XiLingHost
2022-04-18 18:28:03 +08:00
根据鸽笼原理,要让无限长的原始数据的 hash 无冲突,你的 hash 算法的结果空间就必须是无限大的,那么这还有什么 hash 的意义吗
3dwelcome
2022-04-18 18:29:55 +08:00
@oneisall8955 查找算法和插入一样的,先用多层 bitmap 前置过滤一次,有可能会计算多次 hash 函数。

计算后得到不冲突的沙砾层数,这时候对应的 map ,在当前层内查找 key ,就是无冲突的。
XiLingHost
2022-04-18 18:31:57 +08:00
@3dwelcome 所以你的查找需要用原始数据来查原始数据......?
3dwelcome
2022-04-18 18:35:09 +08:00
@XiLingHost "所以你的查找需要用原始数据来查原始数据......?"

这里的 bitmap 相当于 AI 网络的训练数据,对于可预测的原始数据,是最精确的。

如果没有事先插入元素的话,map 是查不到 key 的。
cxtrinityy
2022-04-18 19:17:19 +08:00
嗯, 你这不能叫完美 hash 吧?
我没记错的话, java 的 hashmap 不就是这样么, 相同 hash 会放到一个数组里而已, 而不是新建一个 hashmap
3dwelcome
2022-04-18 19:24:06 +08:00
我说一下使用场景,比如用户上传海量的图片,你单用 md5 或者 sha1 ,都不能保证完美无冲突。
有冲突的话,只能挨个字节对比两张图片是否一模一样,效率是很低的。
这时候,引入砂砾过滤层,如果 md5 有冲突,就把 bitmap 设置成 1 ,那么 hash 算法就会切换到 sha1 。还冲突,就再升一层变成 sha256 ,直到完全无冲突。
3dwelcome
2022-04-18 19:33:18 +08:00
@cxtrinityy 应用场景不一样,java 的 hashmap 冲突后,会进一步对比原始数据。
我这种完美 hash ,保证没冲突,就自然不需要保存原始数据了。
newtype0092
2022-04-18 20:23:17 +08:00
"这时候,引入砂砾过滤层,如果 md5 有冲突,就把 bitmap 设置成 1 ,那么 hash 算法就会切换到 sha1 。还冲突,就再升一层变成 sha256 ,直到完全无冲突。"
也就是你的每个文件都要保存所有 hash 算法的结果,才能让后来比较的文件碰撞时可以不断“升级”算法,比较高一层的 hash 结果。。。
duke807
2022-04-18 20:28:12 +08:00
建立 op 看一下 python 的 dict 實現
3dwelcome
2022-04-18 20:45:46 +08:00
@newtype0092 保存结果就仅仅是 bitmap 里的一个 bit 而已,代表着需要用第几层 hash 算法。基本不占多少存储空间。
3dwelcome
2022-04-18 20:47:26 +08:00
@duke807 如果遍历本地硬盘所有文件,py 的 dict 肯定不能保证没有哈希冲突,我这个就可以。
onehao28
2022-04-18 21:18:00 +08:00
.....
XiLingHost
2022-04-18 21:35:39 +08:00
要不你搞个 PoC 出来给我们看看吧
Talk is cheap. Show me the code
icyalala
2022-04-18 21:44:13 +08:00
......
Perfect Hashing 是个已有概念,但和你描述的东西没有任何关系
creedowl
2022-04-18 21:49:39 +08:00
第一眼还以为是布隆过滤器。。
就 OP 说的比较图片(文件)冲突的场景,我了解到有一种方法是保存整个文件的 hash 和其中部分分块的 hash (阿里云盘)

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/847716

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX