字符串kmp&exkmp&马拉车(刷题总结)

时间:2021-03-29 22:13:47

1、KMP

  1.1、kmp算法需先对模式串建立fail数组,数组所包含的信息就是比如fail[i]表示前缀s[1...i]的最大border长度。

     若 0 ≤ r < |s|, pre(s, r) = suf(s, r), 就称 pre(s, r) 是 s 的 border。 

    也就是当匹配完第i个字符后,假设我们已经到了模式串的第match位,如果S[match+1]!=P[i+1],则match=fail[match],转成最大border,使模式串能更快的与匹配串对齐。

    利用kmp匹配失败后又再次对齐,就可以解决查找一个串在另一个串中的出现次数(考虑或不考虑重叠)。

  1.2、len-fail[len-1]即串中循环节的长度。

  1.3、可以做一些和前缀有关的dp,dp[i]=dp[ fail[i] ]+1.

2、最小最大表示法

  即求在一个字符串的循环同构体中,哪一个字典序最小/大。

3、stl string

  时间复杂度似乎大一点点,但对于暴力是个不错的选择。

4、exkmp

  O(N)求一个字符串的所有后缀与另一个字符串的最长公共前缀。

5、manacher

  需先预处理成偶数形式(每隔两个字符一个‘#’),令p[i]表示以i为对称中心的回文串的半径,线性扫描处理。

  好吧举个例子

  aaaabaaaa

  假设我们求到了上面那个琥珀色的a,因为我们已经求过b了,所以可知

  aaaabaaaa

  左右两个是对称的,所以右边琥珀色的a就可以继承左边琥珀色的a的长度,当然也有限制

  len=mx>i?min(p[2*id-i],mx-i):1; ,mx为记录的最大右端点值,即b的右端点。

  改一改就可以解决凹凸型回文子串问题。