何为字符串哈希
所谓字符串哈希,即对一个字符串形成单向加密的过程,使其产生一个数字映射,通过这种低概率的编号重复,使得字符串的匹配尽可能高效。
如何字符串哈希
最普遍的字符串哈希方式,即进制哈希。核心是将字符串上的每一个字符理解为一个数字,然后固定一个进制,将该字符串转化成一个该进制下的的数,作为其哈希值,然后通过比对哈希值,判断两个字符串是否相等。
len = (int)strlen(s + 1);
for (int i = 1; i <= len; i++)
{
Hash[i] = (Hash[i - 1] * base + s[i] - 'a' + 1) % mod1;
}
}
而对于再好的哈希,也不可避免会产生冲突,此时可以通过一些方法来尽可能降低哈希冲突。
1.无错哈希
原理就是当一个字符串得到一个哈希值后,判定该哈希值是否已经使用过,如果使用的话就不断加上一个大质数,使得不产生冲突。该方式的缺陷在于会十分消耗空间。
2.多重哈希
给定不唯一的哈希函数,对每一个字符串生成多个哈希值,由此来判断两个字符串是否相等。该方法会增加空间和时间,但也提高了正确性。
3.子串哈希
数组
H
a
s
h
\;Hash\;
Hash记录了字符串每个前缀的
H
a
s
h
\;Hash\;
Hash值,通过
H
a
s
h
\;Hash\;
Hash数组可以在
O
(
1
)
\;O\left ( 1\right)
O(1)内计算出其子串的
H
a
s
h
\;Hash\;
Hash值,计算公式为:
H
a
s
h
[
l
.
.
.
r
]
=
(
(
H
a
s
h
[
r
]
−
H
a
s
h
[
l
−
1
]
∗
b
a
s
e
r
−
l
+
1
)
%
m
o
d
+
m
o
d
)
%
m
o
d
Hash\left [ l...r \right]=\left ( \left ( Hash\left [ r \right]-Hash\left [ l-1 \right]*base^{r-l+1} \right)\%mod+mod \right)\%mod
Hash[l...r]=((Hash[r]−Hash[l−1]∗baser−l+1)%mod+mod)%mod
这里之所以
+
m
o
d
\;+mod\;
+mod是因为考虑到前面的减法可能会产生负数,所以
+
m
o
d
\;+mod\;
+mod进行修正。
4.进制哈希
对于一个字符串而言,可以同样预处理的 H a s h \;Hash\; Hash值在 O ( 1 ) \;O(1)\; O(1)的时间内得到一个子串的 H a s h \;Hash\; Hash值,那么子序列的 H a s h \;Hash\; Hash值如何计算呢?换句话说,多个子串拼接而成的新字符串的 H a s h \;Hash\; Hash值该如何求解。这里就要理解 H a s h \;Hash\; Hash函数的含义—— H a s h \;Hash\; Hash函数是将 一个字符串映射为一个 k \;k\; k进制数的过程,所以当我们想得到 s l s l + 1 . . . s x − 1 s x + 1 . . . s r − 1 s r \;s_ls_{l+1}...s_{x-1}s_{x+1}...s_{r-1}s_r\; slsl+1...sx−1sx+1...sr−1sr的 H a s h \;Hash\; Hash值时,只需要将得到 H a s h [ l . . . x − 1 ] \;Hash[l...x-1]\; Hash[l...x−1]左移 r − x \;r-x\; r−x位,然后再放入 H a s h [ x + 1... r ] \;Hash[x+1...r]\; Hash[x+1...r]即可。即 H a s h [ s l . . . s x − 1 s x + 1 . . . s r ] = H a s h [ s l . . . s x − 1 ] ∗ b a s e r − x + H a s h [ s x + 1 . . . s r ] \;Hash[s_l...s_{x-1}s_{x+1}...s_r]=Hash[s_l...s_{x-1}]*base^{r-x}+Hash[s_{x+1}...s_r]\; Hash[sl...sx−1sx+1...sr]=Hash[sl...sx−1]∗baser−x+Hash[sx+1...sr]
完结撒花!