题目描述
KMP算法是字符串模式匹配算法中较为高效的算法之一,其在某次子串匹配母串失败时并未回溯母串的指针而是将子串的指针移动到相应的位置。严蔚敏老师的书中详细描述了KMP算法,同时前面的例子中也描述了子串移动位置的数组实现的算法。前面你已经实现了子串移动的数组,现在就来利用该数组来实现KMP模式匹配。下面是相应的算法:图:KMP算法输入
3组字符串,每组字符串占一行。每行包含由空格分隔的两个字符串,字符串仅由英文小写字母组成且长度不大于100。输出
每组数据输出1行,输出后一个字符串在前一个字符串中的位置,如果不匹配,则输出0。样例输入
string str
thisisalongstring isa
nosubstring subt
样例输出
1
5
0
提示
收起提示[-]提示:
表示字符串的数据结构依然是字符数组。
总结:
KMP算法调用很简单,但难的是理解算法的思想。掌握算法的思想才能说是掌握算法。
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
typedef struct
{
char *ch;
}SString;
void InitString(SString *P);
void StrAssign(SString *P,char charc[]);
void Get_next(SString *P,int next[]);
int Index_KMP(SString *S,SString *T,int next[]);
void InitString(SString *P)
{
P->ch='\0';
return ;
}
void StrAssign(SString *P,char charc[])
{
int i,len;
if(P->ch)
free(P->ch);
len=strlen(charc);
if(!charc)
{
P->ch='\0';
}
else
{
P->ch=(char *)malloc((len+1)*sizeof(char));
if(!P->ch)
{
exit(-1);
}
else
{
for(i=0;i<len;i++)
{
P->ch[i+1]=charc[i];
}
P->ch[0]=len;
}
}
return ;
}
void Get_next(SString *P,int next[])
{
int i=1;
next[1]=0;
int j=0;
while(i<P->ch[0])
{
if(j==0||P->ch[i]==P->ch[j])
{
++i;
++j;
next[i]=j;
}
else
j=next[j];
}
return ;
}
int Index_KMP(SString *S,SString *T,int next[])
{
int i=1,j=1;
while(i<=S->ch[0]&&j<=T->ch[0])
{
if(S->ch[i]==T->ch[j])
{
++i;
++j;
}
else
{
j=next[j];
if(j==0)
{
i++;
j=1;
}
}
}
if(j==T->ch[0]+1)
return i-T->ch[0];
else
return 0;
}
int main()
{
int i,pos;
int Next[100];
char chara[101];
char charb[101];
SString S,T;
for(i=0;i<3;i++)
{
InitString(&S);
InitString(&T);
scanf("%s%s",chara,charb);
StrAssign(&S,chara);
StrAssign(&T,charb);
Get_next(&T,Next);
pos=Index_KMP(&S,&T,Next);
printf("%d\n",pos);
}
return 0;
}