【问题标题】:Java Hash table keys. Converting String keys to int keysJava 哈希表键。将 String 键转换为 int 键
【发布时间】:2013-04-14 17:18:09
【问题描述】:

我有一个家庭作业,我必须为字典创建一个哈希表,用户可以在其中输入一个单词作为键,它将搜索并显示含义。

但是我不确定从 String 键到 int 键的转换是如何工作的。这是我从教科书中获取的代码:

 public int hashVal(String key, int tableSize)
{
    int hashKey= 0;
    int temp = 0;
    for(int i=0;i<key.length();i++)
    {
        temp = 37*temp+(int)key.charAt(i);
    }
    temp%=tableSize;
    if (temp<0)
    {
        temp+=tableSize;
    }
    hashKey=temp;
    return hashKey;
}

非常感谢您提供解释或更简单的代码。

【问题讨论】:

  • 这会计算你的字符串的哈希值。 temp 计算是不必要的,因为 string.hashCode() 会这样做(除非你也需要实现它)。 mod 操作将 hashCode 减少为哈希索引。整数可以溢出到负数,因此也可以处理。

标签: java hashtable


【解决方案1】:

字符串(或任何一般对象)散列的基本思想是使用输入的所有部分,以便我们得到一个相当随机和分布的值。

所以对于一个字符串,我们使用字符串中的所有字符来计算哈希值。 同样,对于一个对象,建议在计算哈希值时使用对象中的所有重要字段。

Java,类似地使用您教科书代码的变体。

问题:为什么你的教科书使用 37? [Java 类似地使用您的教科书代码的变体,将 31 作为常量值]

答案:使用素数显然可以更好地分布整个表中的哈希值。

【讨论】:

    【解决方案2】:

    您的代码有几个冗余。您的哈希计算 - 虽然不一定不正确 - 也是非标准的。我不确定它是否会产生良好的分布,我认为答案是否定的。

    我建议两个修改:使用37 * (int)key.charAt(i) + hash,并去掉临时变量。

    这就变成了:

    public static int hashVal(String s, int max) {
        int hash = 0;
        for(Char c : s.toCharArray())
            hash = Math.abs((hash + 37*(int)c) % max);
        return hash;
    }
    

    【讨论】:

    • 更改方法的返回类型。您打算如何使用负散列来表示 0 -> N 之间的数组索引?
    • 是的,负散列索引到底有什么用?并感谢您的回复。
    • @ShuaibParker 对,我的错。已编辑。如果你只是保持在绝对值下,应该没有问题。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-10-27
    • 2012-12-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-08-24
    相关资源
    最近更新 更多