【问题标题】:Help using Horner's rule and hash functions in Java?帮助在 Java 中使用 Horner 规则和散列函数?
【发布时间】:2010-05-01 21:36:21
【问题描述】:

我正在尝试使用霍纳规则将单词转换为整数。我理解它是如何工作的,如果这个词很长,它可能会导致溢出。我的最终目标是在哈希函数 h(x)=x mod tableSize 中使用转换后的整数。我的书建议,由于溢出,您可以“在计算霍纳规则中的每个括号表达式后应用 mod 运算符”。我不完全明白他们的意思。假设表达式如下所示:

((14*32+15)*32+20)*32+5

我是否在每个带括号的表达式之后取 mod tableSize 并将它们加在一起?这个散列函数和这个霍纳规则的例子会是什么样子?

【问题讨论】:

    标签: java hashtable


    【解决方案1】:

    这本书说你应该利用这些数学等价性:

    (a * b) mod m = ((a mod m) * (b mod m)) mod m
    (a + b) mod m = ((a mod m) + (b mod m)) mod m
    

    因此,

    h = (((x*c) + y)*c + z) mod m
    

    相当于

            _   _   _  _
    h = (((x*c) + y)*c + z)
    

    在哪里

      _
    a * b = ((a mod m) * (b mod m)) mod m
      _
    a + b = ((a mod m) + (b mod m)) mod m
    

    基本上,对于每个基本加法和基本减法,您都将其替换为以mod 操作数和mod 结果的“高级”版本。由于基本乘法的操作数现在在0..m-1 的范围内,因此您将得到的最大数字是(m-1)^2,如果m 足够小,它可以缓解溢出。

    另见


    顺便说一句,应该指出,对于此类的哈希函数(因为它不是素数),尤其是计算(因为它是 2 的幂),32 是一个糟糕的乘数选择。更好的是 31,因为:

    • 质数(数学上很重要!)
    • 它比 2 的幂小一,因此可以优化为更便宜的移位和减法
      • 31 * i == (i << 5) - i

    【讨论】:

      【解决方案2】:

      他们的意思是用该结果 mod tableSize 替换带括号的表达式的结果:

      ((((14*32+15)%tableSize)*32+20)%tableSize)*32+5
      

      【讨论】:

        【解决方案3】:

        使用 Java 代码更容易理解这一点。我们应该在循环内计算的每一步应用模运算符:

        public static int hashCode(String key) {
            int hashVal = 0;
            for (int j = 0; j < key.length(); j++) {
                // For small letters.
                int letter = key.charAt(j) - 96; 
                hashVal = (hashVal * 32 + letter) % arraySize; // mod
            }
            return hashVal;
        }
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2011-03-19
          • 1970-01-01
          相关资源
          最近更新 更多