我有整数数组,例如
[1, 3, 5],
[7, 2, 10],
[50, 12, 10],
[20, 1, 34],
我试图制作一个散列算法,给定其中一个数组会为每个数组返回一个唯一的散列,以便我可以快速查看它们是否存在于HashMap中。
如果两个数组包含相同的数字集并且数组中的最后一个数字相同,则散列应该相同。
例如
// these are the same because they contain the same numbers and have same last number (5)
Hash([3, 1, 5]) -> 5678326
Hash([1, 3, 5]) -> 5678326
// different hash because the last number in the array is different
Hash([5, 1, 3]) -> 9877124
// different hash because different set of values
Hash([7, 1, 5]) -> 2123466
数组中的值在0到100之间,并且它们都是唯一的(因此数组中没有重复项),并且数组的最大大小为100。
这对于什么是一个非常好的哈希算法?
答案 0 :(得分:2)
计算输入的哈希码,就好像它是一个集合,乘以素数,并添加最后一个元素的哈希码。
沿着
的路线new HashSet<Integer>(Arrays.asList(input)).hashCode() * 31 + input[input.length - 1]
但是对于性能,您可能希望通过循环添加输入项而不是创建HashSet
来手动执行此操作。
请注意,这不会&#34;根据您的要求为每个[输入]&#34; 返回一个唯一的哈希值 - 您需要perfect hash function对于那些可能非常矫枉过正的事情。
答案 1 :(得分:1)
您所描述的是一种奇怪的设置,但实现它的一种方法是使用自定义对象:
public class YourCustomObject {
private final int[] allButLast;
private final int last;
public YourCustomObject(int[] value){
this.value = value;
this.allButLast = Arrays.copyOfRange(value, 0, value.length-1);
Arrays.sort(allButLast);
this.last = value[value.length-1];
}
private final int[] value;
@Override
public boolean equals(Object o) {
if (this == o) {
return true;
}else if (( o instanceof YourCustomObject)) {
YourCustomObject that = (YourCustomObject) o;
return last == that.last && Arrays.equals(allButLast, that.allButLast);
} else {
return false;
}
}
@Override
public int hashCode() {
return Objects.hash(allButLast, last);
}
public int[] getValue() {
return value;
}
}
此对象的equals / hashCode属性以任何顺序依赖于相同的数组元素,不包括最后一个元素,它必须相同。您可以将此对象用作HashMap中的键,它将按指定的方式工作。
此外,由于数组是可变的,我可能会在构造函数和getter中制作防御副本。
答案 2 :(得分:0)
不是最优化的解决方案,但它应该做你想做的事情:
int hash(int[] array) {
array = array.clone();
Arrays.sort(array, 0, array.length - 1);
return Arrays.hashCode(array);
}
另一个选择是向集合中添加元素并调用Objects.hash(set, array[array.length - 1])
。
答案 3 :(得分:-2)
如果您只是为了将数组存储在Map或Set的存储区中而需要生成哈希值,则不需要创建自己的哈希函数。 java.util.Arrays
中的那个会做。它们是专门为此目的而设计的。
此外,哈希码不必保证唯一 - 只是不太可能产生冲突。事实上,保证它们的独特性会比偶尔碰撞的速度慢得多。
无需重新发明轮子 - 只需使用java,util.Arrays.hashCode
来计算数组的哈希码。