1.求前缀表next[]
为什么要求前缀表?
如果用暴力的双指针,在失配的时候又从模式串的开头重新匹配,增加了回溯的次数,效率低,复杂度为O(m*n)。
前面已经匹配上的不用再搜索,通过next[]数组,在失去匹配的地方找到该元素的前后缀个数n,移动到模式串的下标n。复杂度时O(m+n)。
通俗来说,next数组存放每个元素之前的字符串,最长公共前后缀的个数。
如何求next[]呢?
Text: A B A B A B A B C A B A A B
Pattern: A B A B C A B A A
最长公共前缀个数 | 前缀 |
---|---|
-1 | |
0 | A |
0 | AB |
1 | ABA |
2 | ABAB |
0 | ABABC |
1 | ABABCA |
2 | ABABCAB |
3 | ABABCABA |
注意 最长前缀最后一个字符是不要的,故把next[0]初始化为-1,对应到模式串的每一个字符。
Pattern: A B A B C A B A A
next[]={-1,0, 0, 1, 2, 0, 1, 2, 3}
1 | void getNext(int next[],string pattern,int n) |
2.KMP的实现过程
主串和匹配串依次匹配,当在失配的地方,查看当前next[i],模式串从Pattern[next[i]]开始进行匹配
haystack:主串
needle:模式串
return:如果能找到,返回主串出现模式串的第一个下标;否则返回-1;
1 |
|