1.简单匹配算法
思想:将目标串S的第一个字符与模式串T的第一个字符进行匹配,若相等,则继续比较S的第二个字符和T的第二个字符;若不相等,则比较S的第二个字符和T的第一个字符,依次比较下去,直到在S中找到与T匹配的或S比较完。时间复杂度为O(M*N)(M=len(S),N=len(T))
算法如下:
//简单匹配算法
int Index(char * S,char * T)
{
assert(S!=NULL && T!=NULL);
int len_S=strlen(S);
int
len_T=strlen(T);
int i=0,j=0;
while(i<len_S && j<len_T)
{
if(S[i]==T[j])
{
i++;
j++;
}
else
{
i=i-j+1;
j=0;
}
}
if(j>=len_T)
return i-j;
return -1;
}
2.KMP算法
kmp算法与普通的匹配算法相比,当S[i]和T[j]不相等时,不回溯i,而是将模式串T“右滑”一段距离,使S[i]与T[K](K<j)开始比较(时间复杂度为O(m+n))
算法实现如下:
//KMP算法
int KMP(char * S,char * T)
{
int len_S=strlen(S);
int len_T=strlen(T);
int * next=new int[len_T];
get_next(T,len_T,next);//构造next数组
int i=0,j=0;//i不用回溯,j要回溯
while(i<len_S && j<len_T)
{
if(j==-1 || S[i]==T[j])
{
i++;
j++;
}
else
j=next[j];
}
if(j>=len_T)
return i-j;
return -1;
}
2.1获得next[]数组的函数
KMP算法的关键是获得next[]数组
(1) next[j]=-1 j=0
(2) next[j]=Max{k|1<k<j 且 T0T1...T(k-1)=T(j-k)...T(j-1)}
(3)next[j]=0 其他情况
获得next数组的算法如下:
//计算模式串T的next[]数组
void get_next(char * T,int n,int next[])//n为的模式串T的长度
{
int i=0,j=-1;
next[0]=-1;
while(i<n-1)
{
if(j==-1 || T[i]==T[j])
{
next[++i]=++j;
}
else
j=next[j];
}
}
2.2获得next[]数组的 改进型函数
//改进的获得next[]的函数
void get_nextval(char * T,int n,int next[])
{
int i=0,j=-1;
next[0]=-1;
while(i<n-1)
{
if(j==-1 || T[i]==T[j])
{
next[++i]=++j;
if(T[i]==T[j])
next[i]=next[j];
}
else
j=next[j];
}
}
//KMP算法
int KMP(char * S,char * T)
{
int len_S=strlen(S);
int len_T=strlen(T);
int * next=new int[len_T];
get_next(T,len_T,next);//构造next数组
int i=0,j=0;//i不用回溯,j要回溯
while(i<len_S && j<len_T)
{
if(j==-1 || S[i]==T[j])
{
i++;
j++;
}
else
j=next[j];
}
if(j>=len_T)
return i-j;
return -1;
}
3.测试
int _tmain(int argc, _TCHAR* argv[])
{
cout<<Index("123456","134")<<endl;
cout<<KMP("123456","134")<<endl;
system("PAUSE");
return 0;
}
4.说明
关于串的匹配KMP算法,数据结构(C语言)严蔚敏版的有较详细的解释,可参考