1. 问题描述
如何在字符串数据中,检测和提取以字符串形式给出的某一局部特征,这类操作都属于串模式匹配(string pattern matching)范畴,简称串匹配。一般的,即对基于同一字符表的任何主串$T(|T|=n)$和模式串$P(|P|=m)$:判定$T$中是否存在某一子串与$P$相同,若存在(匹配),则报告该子串在$T$中的起始位置。
一般串的长度都很大,但相对而言$n$更大,即满足$2<1
2
3T = "Now is the time for all good people to come."
P = "people"
T.indexOf(P) = 29.
2. 求解策略
2.1. 暴力求解
暴力求解是最直观的方法。不妨按自左向右的次序考查各子串。在初始状态下,$T$的前$m$个字符将与$P$的$m$个字符两两对齐。接下来,自左向右检查相互对齐的这$m$对字符:若当前字符对相互匹配,则转向下一对字符;反之一旦失配,则说明在此位置主串与模式串不可能完全匹配,于是可将$P$串右移一个字符,然后从其首字符开始与$T$中对应的新子串重新对比。若经过检查,当前的$m$对字符均匹配,则意味着整体匹配成功,从而返回匹配子串的位置。
暴力求解代码如下:
1 | /* |
代码输出:1
5
当$m<<n$时,上述代码的渐进时间复杂度为$O(nm)$。
2.2. KMP算法
KMP算法详解可参考如下链接:KMP 算法
代码如下:
1 | /* |
代码输出:1
5
上述代码的时间复杂度为$O(n+m)$