kmp算法
先说怎样引出的kmp算法
之前用的都是朴素模式匹配算法,它的基本思想就是:
即从主串的第一个字符开始匹配,一直到最后匹配不上的话,则回到主串的第二个字符进行匹配。就这样一直循环,直到找完所有主串,返回结果。
因为传统的字符串匹配算法会进行很多重复的运算,复杂度太高。所以就引出了kmp算法解决这个问题。
KMP算法
什么是KMP算法?
KMP算法是由三位科学家的开头字母命名而成。
其算法主要思想就是利用之前查找过的字符串的信息,尽量避免回溯重复查找,在已知的子串上根据其特点,计算出如果字母重复的情况下下一个应该开始查找的位置,再与主串进行比对查询,这种算法使得时间复杂度大大减小。O(m+n)
方法总结的过程:
next数组的计算方法:
C++代码描述:
//KMP算法
#include<iostream>
#include<string>
#include<vector>
using namespace std;
void Getnext(int *next,string& T)
{
int i=0;
int j=-1;
next[0]=-1;
while(i<T.size()-1)
{
//T[i]表示后缀的单个字符 T[j]则表示前缀的单个字符
if(j==-1||T[i]==T[j])
{
++i;
++j;
next[i]=j;
}
else
{
j=next[j];//如果字符不相同则进行回溯
}
}
}
//主体就是主串保持不动,子串根据其自身的特点计算出每个字符应该回溯的位置
int GetIndex_KMP(string& S,string& T,int pos)
{
if(S.size()==0||T.size()==0||pos<0)
return -1;
int lenS=S.size();
int lenT=T.size();
int next[255];
Getnext(next,T);
int i=pos;//主串下标
int j=0;//子串下标
while(i<lenS&&j<lenT)
{
//匹配上则直接进行下一个
if(j==-1||S[i]==T[j])
{
i++;
j++;
}
//没有匹配上的话,则获取回溯的位置
else
{
j=next[j];
}
}
if(j>=T.size())
{
return i-T.size();
}
return -1;
}