串的匹配模式操作

串是一种特殊的线性表,其特殊性表现在数据元素是一个字符,也就是说,串是一种串是一种受限的线性表。既然是线性表,那么同样可以有顺序和链式两种结构,但是从总体来看,串在链式存储结构中,他占用存储量大且操作复杂,不如顺序存储结构灵活。串的模式匹配比较著名的有BF算法和KMP算法,下面就用这两种算法,实现模式匹配并计算next值和修正next值。因为有next值和修正next值,所以,KMP算法的用到两次。
【完整代码】

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAXLEN 225

//串的顺序储存结构 
typedef  struct
{
	char ch[MAXLEN+1];
	int length;
}SString;

int Index_BF(SString S,SString T,int pos)
{//返回模式T在主串S中第pos个字符开始第一次出现的位置。若不存在,则返回值为0
	//其中,T非空,1<=pos<=S.length
	int tag1=0; 
	int i=pos,j=0;
	pos=0;
	while(i<=S.length && j<=T.length)	//两个串均未比较到串尾 
	{
		if(S.ch[i]==T.ch[j])	//继续比较后继字符 
		{
			++i;++j;
		}
		else
		{
			i=i-j+1;j=0;		//指针后退重新开始匹配 
		}
		tag1++;
	}
	if(j>T.length)
	//	return i-T.length;
		printf("BF比较%d次	子串位置:%d\n",tag1-1,i-T.length);
	else
		//return 0;
		printf("匹配失败\n"); 
 }
 
int Index_KMP1(SString S,SString T,int next[])
{//利用模式串T的next函数求T在主串S中第pos个字符之后的位置 ,1<=pos<=S.length 
	int i=0,j=0;
	int tag2=0;
//	int next[MAXLEN+1];
	while(i<=S.length && j<=T.length)	//两个串均未比较到串尾 
	{
		if(j==-1||S.ch[i]==T.ch[j])
		{
			++i;++j;			//继续比较后继字符 
		}
		else
			j=next[j];		//模串向右移 
		tag2++;
	}
	if(j>T.length)
		//return i-T.length;
		printf("KMP1比较%d次	子串位置:%d\n",tag2-1,i-T.length);
	else
		//return 0;
		printf("匹配失败"); 
} 

int Index_KMP2(SString S,SString T,int next[])
{//利用模式串T的next函数求T在主串S中第pos个字符之后的位置 ,1<=pos<=S.length 
	int i=0,j=0;
	int tag3=0;
	while(i<=S.length && j<=T.length)	//两个串均未比较到串尾 
	{
		if(j==-1||S.ch[i]==T.ch[j])
		{
			++i;++j;			//继续比较后继字符 
		}
		else j=next[j];		//模串向右移 
		tag3++;
	}
	if(j>=T.length)
		//return i-T.length;
		printf("改进KMP比较%d次	子串位置:%d\n",tag3-1,i-T.length);
	else
		//return 0;
		printf("匹配失败"); 
} 

void get_next(SString T,int next[])
{
	int i=0,j=-1;
	next[0]=-1; 
	while(i<T.length)
	{
		if(j==-1||T.ch[i]==T.ch[j])
		{
			++i;++j;next[i]=j;
		}
		else j=next[j];
	}
}

void get_nextval(SString T,int nextval[])
{
	int i=0,j=-1;
	nextval[0]=-1;
	while(i<T.length)
	{
		if(j==-1||T.ch[i]==T.ch[j])
		{
			++i;++j;
			if(T.ch[i]!=T.ch[j]) nextval[i]=j;
			else nextval[i]=nextval[j];
		}
		else j=nextval[j];
	}
}

int main()
{
	int next[1000];
	int nextval[1000];
	int pos; 
	SString S,T;	//S为主串,T为子串 
	printf("请输入主串:\n");
	scanf("%s",S.ch);
	S.length=strlen(S.ch);
	printf("请输入子串:\n");
	scanf("%s",T.ch);
	T.length=strlen(T.ch);
	Index_BF(S,T,pos);
	get_next(T,next);
	Index_KMP1(S,T,next);
	get_nextval(T,nextval);
	Index_KMP2(S,T,nextval);
	return 0;
 } 
 

运行及试验结果:
在这里插入图片描述

发布了35 篇原创文章 · 获赞 8 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/qq_43873385/article/details/104024328
今日推荐