杜鹃哈希碰撞导致溢出

时间:2015-12-01 06:54:04

标签: java algorithm hash stack-overflow collision

我正在尝试使用哈希函数实现cuckoo哈希: hash1:key.hashcode()%capacity hash2:key.hashcode()/ capacity%capacity

使用无限循环检查和重新散列方法将容量加倍。该程序可以在少量数据的情况下正常工作,但是当数据变得很大(大约20k元素)时,程序会不断重复,直到容量溢出为止。

我认为主要是无限重复导致数据具有完全相同的哈希码。在重新散列之后,其他数据可能会获得相同的哈希码并再次导致重新散列。

我已经使用了Java内置哈希码,但是当数据很大时,相同哈希码的可能性仍然很高。即使我修改了一点哈希码方法,最终仍然存在具有相同哈希码的数据。

那么我应该使用哪种哈希方法来防止这种情况?

1 个答案:

答案 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,依此类推。这应该更能解决碰撞问题。

编辑:

  1. 您正在使用+n,这是一个常量。
  2. 2不是在这种情况下使用的主要内容。使用奇素数,3个有效。