回顾/本期梗概
上期我们学习了图论基础(空降链接),本期我们将学习哈希中的字符串哈希。
1、什么是哈希
哈希算法是:通过哈希函数讲字符串、较大的数等转换为能够用变量表示的或者是直接能作为数组下标的数,通过哈希算法转换到的值,称之为哈希值。哈希值可以实现快速查找和匹配。
比如:用数组下标计数法,统计一个字符串中,每种字母出现的次数就是一个简单的哈希,将,每个字母都映射为了对应的ascii码。
2、如何构造哈希
原理:将字符串中的每一个字母都看作是一个数字(例:从a-z,视为1-26);将字符串视为是一个b进制的数。(注意,不能映射为0,因为如果a为0,那么a、aa、aaa的值将都视为0)
比 如 : 可 将 字 符 串 s = " a b c d " 视 为 2 6 进 制 的 整 数 , 则 可 以 计 算 出 :。如果字符串很长。很容易超出long long 的范畴,为防止溢出,我们取一个固定的值 h 用hash(s)%h,使得结果在long long 范围内。
选取两个合适的互质常熟b和h(b<h)其中h要尽可能的大一点,为了降低冲突(不同字符串计算到一个哈希值)的概率。
一般来说:b取131或13331,h取,最终产生的哈希值的冲突的概率极低。
假设字符串,定义哈希值;
3、滚动哈希优化
如果针对一个很长的字符串,判断其中两个长度为 len 的子串是否相同如果采用的时间复杂度计算出对应的子串 hash ,那和直接取出子串比较的时间复杂度并无差异,因此我们需要使用滚动哈希优化的技巧,可以在的时间复杂度下取出子串的 hash 值。
(1)滚动计算到前缀哈希
设:的字符串 C 前 k 个字符构成的子串的哈希值,(先不考虑取模);
;
类比10进制理解该公式,比如10进制的12345,取出前3个数是123,如果要取出前4个数,可以使用:123*10(进制)+4()=1234的方法取出。
(2)利用前缀哈希计算区间哈希值
设:
因此,求L~R之间的哈希值:
由上述公式可知,只需要预处理出,就可以在的时间内求得任意子串的哈希值
(3)时间复杂度
综上,如果在一个长度为 n 的字符串中,任意取长度为 m 的子串进行匹配,时间复杂度为。
制作不易,点个赞吧!!!
制作不易,点个赞吧!!!
制作不易,点个赞吧!!!