📜  使用多项式滚动散列函数字符串散列(1)

📅  最后修改于: 2023-12-03 15:22:23.559000             🧑  作者: Mango

使用多项式滚动散列函数字符串散列

介绍

散列函数(Hash Function)是一种将任意长度的数据映射到固定长度值的函数,常见的散列函数有 MD5、SHA-1 等。字符串散列是指将字符串映射成一个固定长度的值。

多项式滚动散列函数是一种常用的字符串散列算法,它可以将一个字符串映射成一个整数 hash 值。它的本质是将一个字符串当做一个次数最高项次数为 $n-1$ 的多项式,用某个素数 $p$ 取模得到一个值作为字符串的 hash 值。随着添加新字符,我们用多项式加法更新多项式值。这种方法的时间复杂度为 $O(n)$,但它在大约 1/4 的情况下误判率非常低,而且实现起来非常简单。

多项式滚动散列函数的一个特点是它可以在 $O(n)$ 时间复杂度内在给定的字符串中添加或删除一个字符。因此,当我们需要频繁地判定一个字符串的散列值时,使用多项式滚动散列函数将会非常高效。

实现

以下是一个使用多项式滚动散列函数字符串散列的 Python 代码示例:

def polynomial_rolling_hash(s: str, p: int = 31, m: int = 10**9+9) -> int:
    """
    多项式滚动散列函数

    :param s: 字符串
    :param p: 素数
    :param m: 取模值
    :return: 散列值
    """
    n = len(s)
    # 计算 p 的次幂
    power_of_p = [1]
    for i in range(1, n):
        power_of_p.append(power_of_p[-1] * p % m)

    # 计算字符串的 hash 值
    hash_value = 0
    for i in range(n):
        hash_value = (hash_value + ord(s[i]) * power_of_p[n - 1 - i]) % m

    return hash_value
使用

我们可以使用上面实现的函数计算一个字符串的散列值:

s = "hello world"
hash_value = polynomial_rolling_hash(s)
print(hash_value)

输出:

649081199

对于两个字符串,如果它们的散列值相同,那么它们很有可能是相等的。我们可以使用多项式滚动散列函数来判断两个字符串是否相等,示例代码如下:

def is_equal(s1: str, s2: str) -> bool:
    hash1 = polynomial_rolling_hash(s1)
    hash2 = polynomial_rolling_hash(s2)
    return hash1 == hash2
总结

多项式滚动散列函数是一种高效的字符串散列算法,它的特点是可以在 $O(n)$ 时间内计算一个字符串的散列值,并且可以在 $O(1)$ 的时间内在给定字符串中添加或删除一个字符。在实际应用中,多项式滚动散列函数常常被用于字符串匹配、字符串比较、字符串排序等问题。