实验题3:实现顺序串的各种模式匹配算法(即BF和KMP算法)设计
内容:
编写一个程序,实现顺序串的各种模式匹配运算,并在此基础上完成如下功能:
(1)建立“abcabcdabcdeabcdefabcdef
(2)采用简单匹配算法求t在s中的位置。
(3)由模式串t求出next值和nextval值。
(4)采用KMP算法求t在s中的位置。
(5)采用改进的KMP算法求t在s中的位置。
代码:
#include <stdio.h>
#define MaxSize 100 //最多的字符个数
typedef struct
{
char data[MaxSize]; //定义可容纳MaxSize个字符的空间
int length; //标记当前实际串长
} SqString;
void StrAssign(SqString &s,char cstr[]) //s为引用型参数
{
int i;
for (i=0; cstr[i]!='\0'; i++)
s.data[i]=cstr[i];
s.length=i;
}
void DispStr(SqString s)
{
int i;
if (s.length>0)
{
for (i=0; i<s.length; i++)
printf("%c",s.data[i]);
printf("\n");
}
}
int Index(SqString s,SqString t) //简单匹配算法
{
int i=0,j=0;
while (i<s.length && j<t.length)
{
if (s.data[i]==t.data[j]) //继续匹配下一个字符
{
i++; //主串和子串依次匹配下一个字符
j++;
}
else //主串、子串指针回溯重新开始下一次匹配
{
i=i-j+1; //主串从下一个位置开始匹配
j=0; //子串从头开始匹配
}
}
if (j>=t.length)
return(i-t.length); //返回匹配的第一个字符的下标
else
return(-1); //模式匹配不成功
}
void GetNext(SqString t,int next[])
{
int j,k;
j=0;
k=-1;
next[0]=-1;
while(j<t.length-1)
{
if(k==-1||t.data[j]==t.data[k])
{
j++;
k++;
next[j]=k;
}
else
k=next[k];
}
}
int KMPIndex(SqString s,SqString t)
{
int next[MaxSize],i=0,j=0;
GetNext(t,next);
while(i<s.length&&j<t.length)
{
if(j==-1||s.data[i]==t.data[j])
{
i++;
j++;
}
else
j=next[j];
}
if(j>=t.length)
return(i-t.length);
else
return(-1);
}
void GetNextval(SqString t,int nextval[]) //由模式串t求出nextval值
{
int j=0,k=-1;
nextval[0]=-1;
while (j<t.length)
{
if (k==-1 || t.data[j]==t.data[k])
{
j++;
k++;
if (t.data[j]!=t.data[k])
nextval[j]=k;
else
nextval[j]=nextval[k];
}
else
k=nextval[k];
}
}
int KMPIndex1(SqString s,SqString t) //修正的KMP算法
{
int nextval[MaxSize],i=0,j=0;
GetNextval(t,nextval);
while (i<s.length && j<t.length)
{
if (j==-1 || s.data[i]==t.data[j])
{
i++;
j++;
}
else
j=nextval[j];
}
if (j>=t.length)
return(i-t.length);
else
return(-1);
}
int main()
{
int j;
int next[MaxSize],nextval[MaxSize];
SqString s,t;
StrAssign(s,"abcabcdabcdeabcdefabcdefg");
StrAssign(t,"abcdeabcdefab");
printf("(1).建立目标串s='abcabcdabcdeabcdefabcdefg'和模式串t='abcdeabcdefab'输出如下:\n");
printf(" 串s:");
DispStr(s);
printf(" 串t:");
DispStr(t);
printf("(2).采用简单匹配算法t在s中的位置: \n");
printf(" t在s中的位置=%d\n",Index(s,t));
printf("(3).由模式串t求出next数组值和nextval数组值\n");
GetNext(t,next); //由模式串t求出next值
GetNextval(t,nextval); //由模式串t求出nextval值
printf(" j ");
for (j=0; j<t.length; j++)
printf("%4d",j);
printf("\n");
printf(" t[j] ");
for (j=0; j<t.length; j++)
printf("%4c",t.data[j]);
printf("\n");
printf(" next ");
for (j=0; j<t.length; j++)
printf("%4d",next[j]);
printf("\n");
printf(" nextval");
for (j=0; j<t.length; j++)
printf("%4d",nextval[j]);
printf("\n");
printf("(4).采用KMP算法求t在s中的位置:\n");
printf(" t在s中的位置=%d\n",KMPIndex(s,t));
printf("(5).采用改进的KMP算法求t在s中的位置:\n");
printf(" t在s中的位置=%d\n",KMPIndex1(s,t));
return 0;
}