5

我正在复习我的数据结构期末考试,我在去年的期末考试中遇到了一个问题。在过去三个小时的工作中,我仍然无法找到解决它的方法,除非通过反复试验。这是问题:

“假设你的哈希表的大小是 31,常数 g 也是 31,并且你使用下面的哈希码

int hash = 0;
int n = s.length();
for (int i = 0; i < n; i++)
   hash = g * hash + s.charAt(i);

并且您使用单独的链接来解决冲突。列出五个不同的名称,它们将散列到表中的同一位置。”

我认为必须有某种技巧,可能涉及模运算符来解决这个问题,考虑到哈希表的大小为 31,与常数 g 相同。对不起,如果我听起来像这样,但我不是要代码或任何东西,只是对这个问题的一些想法/提示。非常感谢任何评论。谢谢

4

2 回答 2

6

java 字符串可以包含零字符 ( "\0"),因此以下所有内容都将散列为相同的值:

"a"
"\0a"
"\0\0a"
"\0\0\0a"
"\0\0\0\0a"

这是证明(感谢 Eric 提供的参考,这是使用的哈希):

> cat Foo.java
class Foo {
    public static void main(String[] args) {                                    
        System.out.println("a".hashCode());                                     
        System.out.println("\0a".hashCode());                                   
        System.out.println("\0a".length());
        System.out.println("\0a".equals("a"));
    }                                                                           
}           
> javac Foo.java                                        
> java Foo                                                       
97
97
2
false

不过,我怀疑这是预期的答案。

另外,如果这是一场考试,我怀疑我能记住 ASCII 码。因此,在另一个答案中使用样式序列的另一种方法是:

"\002\000"
"\001\037"

等(这些是八进制三元组 - 以上都是哈希到 62)。但是为这种风格生成五个示例(所有相同的哈希)是否容易?

于 2012-05-17T03:51:54.383 回答
5

根据Wikipedia article on Java's string hashing algorithm(与您提供的算法相同):

与任何一般的散列函数一样,冲突是可能的。例如,字符串“FB”和“Ea”具有相同的哈希值。String 的 hashCode() 实现使用素数 31,'a' 和 'B' 的差值只有 31,所以计算为 70 × 31 + 66 = 69 × 31 + 97。

于 2012-05-17T03:07:10.953 回答