【发布时间】:2019-07-12 22:35:16
【问题描述】:
问题是,第一个数字已经是 ORACLE LONG,
第二个是日期(SQL DATE,没有额外的时间戳信息),最后一个是 1000-100'000 范围内的 Short 值。
如何以最佳方式创建每种组合唯一的哈希值?
字符串连接并转换为long later:
例如,我不想要这个。
日月
12 1 --> 121
1 12 --> 121
【问题讨论】:
问题是,第一个数字已经是 ORACLE LONG,
第二个是日期(SQL DATE,没有额外的时间戳信息),最后一个是 1000-100'000 范围内的 Short 值。
如何以最佳方式创建每种组合唯一的哈希值?
字符串连接并转换为long later:
例如,我不想要这个。
12 1 --> 121
1 12 --> 121
【问题讨论】:
当您有几个数值并且需要从中获得一个“唯一”(即统计上不可能重复的)值时,您通常可以使用如下公式:
h = (a*P1 + b)*P2 + c
其中 P1 和 P2 要么是精心挑选的数字(例如,如果您知道 'a' 始终在 1-31 范围内,则可以使用 P1=32),或者当您对 a 的允许范围一无所知时,b,c 最好的方法是将 P1 和 P2 作为大素数(它们产生碰撞值的机会最小)。 对于最佳解决方案,数学比这要复杂一些,但是使用素数通常可以得到一个不错的解决方案。
例如,数组(或字符串)的.hashCode() 的 Java 实现类似于:
h = 0;
for (int i = 0; i < a.length; ++i)
h = h * 31 + a[i];
即使就个人而言,我也会选择大于 31 的素数,因为 String 中的值很容易发生冲突,因为 31 位的 delta 可能很常见,例如:
"BB".hashCode() == "Aa".hashCode() == 2122
【讨论】:
你的
12 1 --> 121
1 12 --> 121
问题很容易通过将输入数字填充到每个输入字段的最大宽度来解决。
例如,如果第一个字段的范围可以从 0 到 10000,第二个字段的范围可以从 0 到 100,那么您的示例将变为:
00012 001 --> 00012001
00001 012 --> 00001012
【讨论】:
在python中,你可以这样使用:
#pip install pairing
import pairing as pf
n = [12,6,20,19]
print(n)
key = pf.pair(pf.pair(n[0],n[1]),
pf.pair(n[2], n[3]))
print(key)
m = [pf.depair(pf.depair(key)[0]),
pf.depair(pf.depair(key)[1])]
print(m)
输出是:
[12, 6, 20, 19]
477575
[(12, 6), (20, 19)]
【讨论】: