我编写的代码从文件中读取一些单词及其含义,并将它们映射到数组(make hash table)。它使用多项式哈希码和压缩方法。
我的目标是尽可能减少碰撞,但我不知道如何。
public int hashcode(Entry my){
Object key=my.getKey();
int sum=0 ,z=33;
char[] chars = new char[key.toString().length()];
chars=key.toString().toCharArray();
for(int i=0; i < chars.length; i++){
sum += (chars[i])*Math.pow(z,i);
}
return sum;
}
这是我的压缩方法(对于数组大小为100):
public int compress(int hashcode){
return hashcode%100;
}
我应该改变我的压缩方法还是有方法可以帮助我?
答案 0 :(得分:2)
你似乎正在寻找的是一个完美的哈希函数,不幸的是,据我所知,这样的哈希不存在:)
另一点需要指出的是,散列函数的性能也因您想要实现的结果类型而异;我的意思是哈希函数可能在“存储”电话号码方面表现优异,但在存储联系人姓名方面效果不佳。
通过快速查看代码,我会说你的哈希函数过于复杂
首先,我想指出您当前算法的问题:此行'sum + =(chars [i])* Math.pow(z,i);'对于长度超过4-5个字符的单词,将返回超出整数范围的值(只是猜测)。你可能会说它没关系,因为它会溢出等等但事实是它不会因为sum + =语法实际上隐藏了一个类型转换(尝试将其写为sum = sum +)并且在这种情况下总和将具有Integer.MAX_VALUE的值。这可能就是你的算法现在很慢的原因。
如果我是你,为了字典的目的(这似乎是你想要做的)并假设Entry#getKey()是String类型,我可能会选择:
public int hashcode(Entry my) {
return my.getKey().hashCode();
}
如果你还想提出自己的哈希函数,为什么不去更简单的东西:[字长+前X字母的字母代码+最后一个字母的字母代码]你在哪里调整X所以结果会适合int。只是一个想法:)