哈希函数不正确? Math.pow不处理任意大数

时间:2016-07-13 20:35:09

标签: python

我正在尝试在LintCode上解决这个easy problem,我有我的解决方案:

import math
class Solution:
    """
    @param key: A String you should hash
    @param HASH_SIZE: An integer
    @return an integer
    """
    def hashCode(self, key, HASH_SIZE):
        # write your code here
        ret=0
        for i in range(0,len(key)):
            multiplier=int(math.pow(33,len(key)-i-1))
            ret += (multiplier* ord(key[i]))
        return ret%HASH_SIZE

但它仅适用于length <= 11的键,否则不起作用(错误答案)。 Python默认处理任意大数,所以问题是什么?这很简单,弄错了让我发疯。

问题描述:

  

在数据结构Hash中,哈希函数用于转换字符串(或   任何其他类型)到小于散列大小和更大的整数或   等于零。设计哈希函数的目的是“哈希”   关键是尽可能不合理。一个好的哈希函数可以避免   碰撞越少越好。一种广泛使用的哈希函数算法   正在使用幻数33,将任何字符串视为基于33的大字符串   整数如下:

hashcode("abcd") = (ascii(a) * 333 + ascii(b) * 332 + ascii(c) *33 +
ascii(d)) % HASH_SIZE 

                          = (97* 333 + 98 * 332 + 99 * 33 +100) % HASH_SIZE

                          = 3595978 % HASH_SIZE
     

这里HASH_SIZE是哈希表的容量(你可以假设一个   哈希表就像一个索引为0~HASH_SIZE-1的数组。

     

给定字符串作为键和散列表的大小,返回散列   这个key.f

的价值

更新:Rob的回答解决了错误答案的问题,但现在速度是一个问题。

UPDATE2: 以下两种技术都有效:

        ret=0
        ## technique 1
        for i in range(0,len(key)):
            multiplier= pow(33,(len(key)-i-1),HASH_SIZE)
            ret += (multiplier * ord(key[i]))
        return ret%HASH_SIZE
        # technique 2
        ret=0
        multiplier = 1
        for ch in key[::-1]:
            ret = (ret + ord(ch) * multiplier) % HASH_SIZE
            multiplier = (multiplier * 33) % HASH_SIZE
        return ret % HASH_SIZE

2 个答案:

答案 0 :(得分:3)

  
    

Python默认处理任意大数字

  

是的,它确实如此,但只有整数是任意大的。 math.pow()处理浮点数,它有大小限制。

尝试:

#UNTESTED
multiplier=33**(len(key)-i-1)

答案 1 :(得分:3)

将引导您找到解决方案的一对事实:

  1. pow(x, y, [z])内置函数将准确计算(x ** y) % z,而不涉及任意长度的整数。

  2. (a + b + …) % x(a%x + b%x + …) % x相同。 (也就是说,您可以在总和中执行模数运算而不会影响结果。)