搜档网
当前位置:搜档网 › 串的匹配

串的匹配

串的匹配
串的匹配

实验4-1 串的匹配

1、实验目的

了解串的特点,描述方法及有关概念,掌握串的模式匹配算法。

2、实验内容

已知主串为"aaabaaaab",子串为"aaaab",求模式串的next值和nextval值,实现模式串的匹配算法。

3、实验要点及说明

模式匹配:子串的定位操作通常称为串的模式匹配。它是各种串处理系统中最重要的操作之一。

模式匹配的算法基本思想是:从主串S的第pos 个字符起和模式的第一个字符比较之,若相等,则继续逐个比较后续字符;否则从主串的下一个字符起再重新和模式的字符比较之。依次类推,直至模式T中的每个字符依次和主串S中的一个连续的字符序列相等,则称匹配成功,函数值为和模式T中第一个字符相等的字符在主串S中的序号,否则称为匹配不成功,函数值为零。

改进的模式匹配算法:每一趟匹配过程中出现字符比较不等时,不需回溯i指针,而是利用已经得到的“部分匹配”的结果将模式向右“滑动”尽可能的一段距离后,继续进行比较。

在改进的模式匹配算法(KMP算法)中,当匹配过程中产生“失配”时,指针i不变,指针j退回到next[j]所指示的位置上重新进行比较,并且当指针j退至零时,指针i和指针j需同时增1。即若主串的第i个字符和模式的第1个字符不等,应从主串的第i+1字符重新进行匹配。

4、参考程序

#include

#include

#include

#include

#define MAX_STR_LEN 40 /* 用户可在255(1个字节)以内定义最大串长 */

typedef char SString[MAX_STR_LEN+1]; /* 0号单元存放串的长度 */

void StrAssign(SString T,char *chars)

{ /* 生成一个其值等于chars的串T */

int i;

if(strlen(chars)>MAX_STR_LEN)

exit(0);

else

{

T[0]=strlen(chars);

for(i=1;i<=T[0];i++)

T[i]=*(chars+i-1);

}

}

int StrLength(SString S)

{ /* 返回串S的元素个数 */

return S[0];

}

void get_next(SString T,int next[])

{ /* 求模式串T的next函数值并存入数组next。算法4.7 */

int i=1,j=0;

next[1]=0;

while(i

if(j==0||T[i]==T[j])

{

++i;

++j;

next[i]=j;

}

else

j=next[j];

}

void get_nextval(SString T,int nextval[])

{ /* 求模式串T的next函数修正值并存入数组nextval。算法4.8 */

int i=1,j=0;

nextval[1]=0;

while(i

if(j==0||T[i]==T[j])

{

++i;

++j;

if(T[i]!=T[j])

nextval[i]=j;

else

nextval[i]=nextval[j];

}

else

j=nextval[j];

}

int Index_KMP(SString S,SString T,int pos,int next[])

{ /* 利用模式串T的next函数求T在主串S中第pos个字符之后的位置的KMP算法。 */ /* 其中,T非空,1≤pos≤StrLength(S)。算法4.6 */

int i=pos,j=1;

while(i<=S[0]&&j<=T[0])

if(j==0||S[i]==T[j]) /* 继续比较后继字符 */

{

++i;

++j;

}

else /* 模式串向右移动 */

j=next[j];

if(j>T[0]) /* 匹配成功 */

return i-T[0];

else

return 0;

}

void StrPrint(SString T)

{ /* 输出字符串T。另加 */

int i;

for(i=1;i<=T[0];i++)

printf("%c",T[i]);

printf("\n");

}

void main()

{

int i,*p;

SString s1,s2; /* 以教科书算法4.8之上的数据为例 */

StrAssign(s1,"aaabaaaab");

printf("主串为: ");

StrPrint(s1);

StrAssign(s2,"aaaab");

printf("子串为: ");

StrPrint(s2);

p=(int*)malloc((StrLength(s2)+1)*sizeof(int)); /* 生成s2的next数组空间 */ get_next(s2,p); /* 利用算法4.7,求得next数组,存于p中 */

printf("子串的next数组为: ");

for(i=1;i<=StrLength(s2);i++)

printf("%d ",*(p+i));

printf("\n");

i=Index_KMP(s1,s2,1,p); /* 利用算法4.6求得串s2在s1中首次匹配的位置i */ if(i)

printf("主串和子串在第%d个字符处首次匹配\n",i);

else

printf("主串和子串匹配不成功\n");

get_nextval(s2,p); /* 利用算法4.8,求得next数组,存于p中 */

printf("子串的nextval数组为: ");

for(i=1;i<=StrLength(s2);i++)

printf("%d ",*(p+i));

printf("\n");

printf("主串和子串在第%d个字符处首次匹配\n",Index_KMP(s1,s2,1,p)); }

相关主题