我正在尝试使用哈希函数实现cuckoo哈希: hash1:key.hashcode()%capacity hash2:key.hashcode()/ capacity%capacity
使用无限循环检查和重新散列方法将容量加倍。该程序可以在少量数据的情况下正常工作,但是当数据变得很大(大约20k元素)时,程序会不断重复,直到容量溢出为止。
我认为主要是无限重复导致数据具有完全相同的哈希码。在重新散列之后,其他数据可能会获得相同的哈希码并再次导致重新散列。
我已经使用了Java内置哈希码,但是当数据很大时,相同哈希码的可能性仍然很高。即使我修改了一点哈希码方法,最终仍然存在具有相同哈希码的数据。
那么我应该使用哪种哈希方法来防止这种情况?
答案 0 :(得分:1)
创建哈希函数的常用方法通常是使用素数。我写了一个函数(下面),我不保证没有碰撞,但应该减少它。
hashFunction1(String s){
int k = 7; //take a prime number, can be anything (I just chose 7)
for(int i = 0; i < s.length(); i++){
k *= (23 * (int)(s.charAt(i)));
k %= capacity;
}
}
//23 is another randomly chosen number.
您可以编写类似哈希函数hashFunction2,选择两个不同的素数。但是在这里,主要的问题是,对于字符串“stop”和“pots”,这给出了相同的哈希码。
因此,对此功能的改进可以是:
hashFunction1(String s){
int k = 7; //take a prime number, can be anything (I just chose 7)
for(int i = 0; i < s.length(); i++){
k *= (23 * (int)(s.charAt(i)));
k += (int)(s.charAt(i));
k %= capacity;
}
}
将解决此问题(对于大多数情况,如果不是全部的话)。
如果你仍然发现这个函数不好,而不是s.charAt(i),你可以使用映射到每个字符的唯一素数,即。 a = 3,b = 5,c = 7,d = 11,依此类推。这应该更能解决碰撞问题。
编辑:
+n
,这是一个常量。2
不是在这种情况下使用的主要内容。使用奇素数,3个有效。