接下来我把经典的kmp算法分为两步来行动
第一步,先将模式串做好相应的标志位
核心思想:解释起来比较抽象,还不如不解释,下面我将直接结合例子来解释
第一步,先将各字符以及各字符在字符串的位置表示出来,用一个int型数组存储各个字符的下标,首先int[0]=-1(表示这是第一个字符),int[1]=0(对应字符串中地址为0的字符),如下所示:
第二步,比较S1刚刚已经确立的地址为1的字符和S2刚刚确立的地址下标为0的字符,如果两者字符相等,则表示下一个地址的字符的下标为现在地址的下标加一(如果a[1]=a[0],a[2]地址的下标就为0+1=1)反之,则直到该字符与字符下标的字符下标的。。。字符相等或字符下标等于-1,则表示下一个地址的字符的下标为现在地址的下标加一(如图,为B的a[1]不等于为A的a[0],又因为a[0]的下标为-1,则a[2]的下标为0)
接下来,按照第二步的算法规则遍历完整个字符串,就得到了如下所示字符下标的排列顺序。
接下来代码如下所示:
#define max 100
int visit[max];
void ap(str str)
{
int i=1;
visit[0]=-1;
visit[1]=0;
//如果前一个字符和对应的字符下标对应的字符相等,相应存储位就加1
//如果不等,就与该下标对应的下标字符对比,直到相等,如果不相等就归为-1
j=visit[i];
while(i<str.length-1)
{
if(str.a[i]==str.a[j])
{
i++;
visit[i]=++j;
}
else
{
while(str.a[i]!=str.a[j]&&j!=-1)
j=visit[j];
i++;
visit[i]=++j;
}
}
}
第二步,开始正式的字符串比对匹配
思想,与上文模式串思想类似,将待匹配的字符串与模式串一个一个位置进行匹配,如果两者相等,则模式串与字符串分别向前移一位匹配,如果不相等,则与模式串的下标进行匹配,直到相等为止,按此规则,直到所有的模式串匹配完,匹配成功返回成功结点的位置,反之返回0;
int pos(str str1,str str2)
{
int i=0,j=0;
//将相应位置的两个字符对比,如果相等,则比对下面两个字符,反
//之,就对比字符下标的的字符,一直到相等或者字符标志为-1即
//可,最后str2.length-1字符匹配成功即可
while(j<str2.length&&i<str1.length)
{
if(a[i]==b[j])
{
i++;
j++;
}
else
{
while(a[i]!=b[j]&&j!=-1)
{
j=next[j];
}
i++;
j++;
}
}
if(j==str2.length)
{
return i-1-str2.length;
}
else//如果没有找到相应匹配的串,就归为0
{
return 0;
}
}