关于串的模式匹配,简单来讲,就是从S串中找到子串T的位置。假设有串S=“acabcabcacbab”,子串T="abcac",这个问题,首先你会怎么做呢?(可以先做思考)
这个问题,在<数据结构>一书中描述得已经足够清楚,本篇特在此进行梳理和回顾。
1.朴素匹配(Brute Force简称BF)
可能你想到的方法刚好就是下面的将要介绍的朴素匹配算法,下面我们看看它的匹配过程:
图1
可以看出,算法是对于主串S和子串逐字符比较,一旦遇到未匹配的字符就从主串中开始匹配的下个位置再进行逐字匹配,比如,在第三趟中主串S中b和子串T中的c不匹配,
那么就需要从主串中开始匹配的字符a(i=3)的下个位置b(i=4)再和子串逐字匹配见第四趟匹配,这样,一直到匹配到子串T或者未找到。算法的实现也很容易理解:
int index(SString S,SString T,int pos)
{
int i,j;
if(1<=pos&&pos<=S[0]){
i=pos;
j=1;
while(i<=S[0]&&j<=T[0]){
if(S[i]==T[j]){
++i;++j;
}else{ //回溯
i=i-j+2;
j=1;
}
}
if(j>T[0])
return i-T[0];
else
return 0;
}
return 0;
}
注:SString 为串的顺序存储结构表示 S[0]存储串的长度,字符索引从1开始,详见<BDS之串>一篇
2.KMP算法
KMP算法是由Knuth(D.E.Knuth)、Morris(J.H.Morris)和Pratt(V.R.Pratt)三