字符串匹配
参考资料:算法导论
字符串匹配问题定义
假设文本是一个长度为 n 的数组 T[ 1.. n ],模式是一个长度为 m <= n 的数组 P[ 1 .. m] 。进一步假设 P 和 T 都是属于有限字母表中的字符。
如果 0 <= s <= n-m ,并且 T[ s+ 1 .. s+m] = P [ 1.. m ] ( 即对 1 <= j <= m ,有 T[s + j] = P[ j ] ),则说该模式P 在文本 T 中出现且位移为 s。
字符串匹配算法比较
算法 | 预处理时间 | 匹配时间 |
---|---|---|
朴素算法 | 0 | O( (n-m+1) m ) |
Rabin-Karp | O ( m) | O ( (n-m +1) m) |
有限自由机算法 | O(m|E|) (|E|:字符集的个数) | O ( n ) |
Knuth-Morris-Pratt ( KMP ) | O ( m ) | O ( n) |
注:
Rabin-Karp在最坏情况下的运行时间为 O( (n-m+1) m ) , 虽然这一时间并不比朴素算法好,但在平均情况和实际情况下,该算法的效果要好得多。这种算法可以很好的推广到解决其他的模式匹配问题中去;
KMP算法设计很巧妙,预处理的时间减少到 O ( m ) 。
记号、术语、引理
1 ∑* 表示用字母表∑中的字符形成的所有有限长度的字符串的集合。
2 字符串 x 的长度用 | x | 表示。两个字符串 x 和 y 的连接表示为 xy ,其长度为 | x | + | y | ,由 x 的字符接 y 的字符组成。
3 如果对于某个字符串 y ∈∑* ,有 x = wy,就说字符串 w 是字符串 x 的前缀,表示为 w 【 x ,| w | <= | x |。类似的,如果对某一个字符串 y ∈∑*,有 x = yw,就说字符串 w 是字符串 x 的后缀,表示为 w 】x 。
重叠后缀引理
假设 x ,y 和 z 是满足 x 】z 和 y 】z 的三个字符串。如果 | x | <= | y |,则x 】y ;如果 | x | >= | y |,则 y 】 x;如果 | x | = | y | ,则 x = y。