From 1098dee9950fec9bc57fbcf660cd5a1389bf45ac Mon Sep 17 00:00:00 2001 From: ITCharge Date: Wed, 19 Jun 2024 15:56:24 +0800 Subject: [PATCH] Update 02.String-Rabin-Karp.md --- .../02.String-Rabin-Karp.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Contents/06.String/02.String-Single-Pattern-Matching/02.String-Rabin-Karp.md b/Contents/06.String/02.String-Single-Pattern-Matching/02.String-Rabin-Karp.md index 16239bff..9df54f97 100644 --- a/Contents/06.String/02.String-Single-Pattern-Matching/02.String-Rabin-Karp.md +++ b/Contents/06.String/02.String-Single-Pattern-Matching/02.String-Rabin-Karp.md @@ -32,17 +32,17 @@ RK 算法中的滚动哈希算法主要是利用了 **「Rabin fingerprint 思 比如 `"cat"` 的哈希值就可以表示为: -$$\begin{aligned} Hash(cat) &= c \times 26 \times 26 + a \times 26 + t \times 1 \cr &= 2 \times 26 \times 26 + 0 \times 26 + 19 \times 1 \cr &= 1371 \end{aligned}$$ +$$\begin{aligned} Hash(cat) &= c \times 26^2 + a \times 26^1 + t \times 26^0 \cr &= 2 \times 26^2 + 0 \times 26^1 + 19 \times 26^0 \cr &= 1371 \end{aligned}$$ 这种按位计算哈希值的哈希函数有一个特点:在计算相邻子串时,可以利用上一个子串的哈希值。 比如说 $cat$ 的相邻子串为 `"ate"`。按照刚才哈希函数计算,可以得出 `"ate"` 的哈希值为: -$$\begin{aligned} Hash(ate) &= a \times 26 \times 26 + t \times 26 + e \times 1 \cr &= 0 \times 26 \times 26 + 19 \times 26 + 4 \times 1 \cr &= 498 \end{aligned}$$ +$$\begin{aligned} Hash(ate) &= a \times 26^2 + t \times 26^1 + e \times 26^0 \cr &= 0 \times 26^2 + 19 \times 26^1 + 4 \times 26^0 \cr &= 498 \end{aligned}$$ 如果利用上一个子串 `"cat"` 的哈希值计算 `"ate"`,则 `"ate"` 的哈希值为: -$$\begin{aligned} Hash(ate) &= (Hash(cat) - c \times 26 \times 26) * 26 + e \times 26 \cr &= (1371 - 2 \times 26 \times 26) \times 26 + 4 \times 1 \cr &= 498 \end{aligned}$$ +$$\begin{aligned} Hash(ate) &= (Hash(cat) - c \times 26^2) \times 26 + e \times 26^0 \cr &= (1371 - 2 \times 26^2) \times 26 + 4 \times 26^0 \cr &= 498 \end{aligned}$$ 可以看出,这两种方式计算出的哈希值是相同的。但是第二种计算方式不需要再遍历子串,只需要进行一位字符的计算即可得出整个子串的哈希值。这样每次计算子串哈希值的时间复杂度就降到了 $O(1)$。然后我们就可以通过滚动哈希算法快速计算出子串的哈希值了。