字符串匹配算法KMP
如leetcode28题,求一个字符串是否和另一个字符串中的子串相匹配,如text = “hello”, pattern = “ll”,匹配的头坐标就是2.
此题通过常规的遍历算法可以解决,算法复杂度就是O(M^N),M是text的字符串长度,N是pattern字符串的长度。
通过KMP算法可以简化算法复杂度,达到O(M+N)的算法复杂度。
KMP算法的核心就是寻找needle子串中是否存在相同的后缀与前缀并记录下来,记录的数组称为next数组,next[j]=k,表示pattern中的子串[j-k,k]与子串[0,k]相等,也可以理解为如果第j个索引匹配失败后pattern指针重新返回的位置。当text与pattern对比的字符不同的时候可以快速的通过next数组来定位到pattern的再次对比的初始位置,不需要从头开始遍历pattern字符串。
- 具体地,通过维护两个指针来构建next数组:
vector<int> getNext(string pattern){
// 数组一开始必须初始化为-1
vector<int> next(pattern.size(), -1);
// j表示记录的重复前缀索引
int j = -1, i = 0;
while(i < (int)pattern.size()-1){
if(j == -1 || pattern[i] == pattern[j]){
next[++i] = ++j;
}else{
j = next[j];
}
}
return next;
}