KMP 算法
1. kmp算法是一种改进的字符串匹配算法,它的关键是利用匹配失败后的信息,尽量减少模式串与主串的匹配次数以达到快速匹配的目的。
2. Kmp算法的空间复杂度:给定两个字符串a和b,长度分别为n和m.判断b是否在a中出现,如果出现则返回出现的位置。常规算法是遍历a的每一个位置,然后从该位置开始和b进行匹配,但是这种方法的复杂度为O(n*m)。Kmp算法通过一个O(m)的预处理,使匹配的复杂度降为O(n+m)。
3.Kmp前缀与后缀概念:借用KMP算法的next数组,设s的长度为n,则s串本身必定满足条件。其他满足条件的子串都有个特征,就是该子串的最后一个字符肯定与s的最后一个字符相同。这正是next数组发挥作用的时候。从n - 1位既最后一位开始回滚,若s[next[n-1]] == s[n-1],则子串s[0,1,2,...,next[n-1]]是满足条件的子串。然后判断s[next[next[n-1]]] == s[n-1]是否成立,这样一直回滚,直到next[next[.....next[n-1]]] == -1为止。把答案从大到小存下来,再从小到大输出即可。
4.next数组的求解思路:
void makeNext(const char P[],int next[])
{
int q,k;//q:模版字符串下标;k:最大前后缀长度
int m = strlen(P);//模版字符串长度
next[0] = 0;//模版字符串的第一个字符的最大前后缀长度为0
for (q = 1,k = 0; q < m; ++q)//for循环,从第二个字符开始,依次计算每一个字符对应的next值
{
while(k > 0 && P[q] != P[k])//递归的求出P[0]···P[q]的最大的相同的前后缀长度k
k = next[k-1]; //不理解没关系看下面的分析,这个while循环是整段代码的精髓所在,确实不好理解
if (P[q] == P[k])//如果相等,那么最大相同前后缀长度加1
{
k++;
}
next[q] = k;
}
}