c语言版数据结构(奇迹冬瓜)-串的匹配模式算法

本文介绍了三种不同的字符串匹配算法:传统匹配模式、KMP匹配模式及其改进版。通过示例代码详细解析了每种算法的工作原理及实现过程,特别是KMP算法中next和nextval数组的构造方法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

[一]传统匹配模式

//-----头文件------
#include<stdio.h>
#include<stdlib.h>

//------宏定义------
#define MAXSTRLEN 255
#define OVERFLOW -2
#define TURE 1
#define ERROR 0

//-------类型名替换--------
typedef unsigned char SString[MAXSTRLEN+1];
typedef int Bool;

//-----函数列表-----
Bool StrAssign(SString *T,char *s);
int Index(SString *S,SString *T,int pos);
void StrOutput(SString S);

//-----主函数做替换测试------
void main()
{
	SString t,*T=&t,s,*S=&s;
	int i;
	StrAssign(T,"abaabcac");
	StrAssign(S,"acabaabaabcacaabc");
	i=Index(S,T,1);
	//StrOutput(s);
	printf("%d\n",i);
	getchar();
	getchar();
}

//------生成一个其值等于字符串常量的串T------
Bool StrAssign(SString *T,char *s)
{
	int i;
	for(i=0;'\0'!=*s;s++,i++)
	{
		(*T)[i+1]=*s;
	}
	(*T)[0]=i;
	return TURE;
}



//-----输出串-----
void StrOutput(SString S)
{
	int i;
	for(i=1;i<=S[0];i++)
	{
		printf("%c",S[i]);
	}
}

int Index(SString *S,SString *T,int pos)
{
	if (1>pos||pos>(*S)[0])
	{
		exit(OVERFLOW);
	}
	int i=pos,j=1;
	while(i<=(*S)[0]&&j<=(*T)[0])
	{
		if((*S)[i]==(*T)[j])
		{
			++i;
			++j;
		}
		else
		{
			i=i-j+2;
			j=1;
		}
	}
	return j>(*T)[0]?i-(*T)[0]:0;
}

[2]KMP匹配模式

//-----头文件------
#include<stdio.h>
#include<stdlib.h>

//------宏定义------
#define MAXSTRLEN 255
#define OVERFLOW -2
#define TURE 1
#define ERROR 0

//-------类型名替换--------
typedef unsigned char SString[MAXSTRLEN+1];
typedef int Bool;

//-----函数列表-----
Bool StrAssign(SString *T,char *s);
int Index_KMP(SString *S,SString *T,int pos);
void get_next(SString *T,int next[]);
void StrOutput(SString S);

//-----主函数做替换测试------
void main()
{
	SString t,*T=&t,s,*S=&s;
	int i;
	StrAssign(T,"abaabcac");
	StrAssign(S,"acabaabaabcacaabc");
	i=Index_KMP(S,T,1);
	//StrOutput(s);
	printf("%d\n",i);
	getchar();
	getchar();
}

//------生成一个其值等于字符串常量的串T------
Bool StrAssign(SString *T,char *s)
{
	int i;
	for(i=0;'\0'!=*s;s++,i++)
	{
		(*T)[i+1]=*s;
	}
	(*T)[0]=i;
	return TURE;
}



//-----输出串-----
void StrOutput(SString S)
{
	int i;
	for(i=1;i<=S[0];i++)
	{
		printf("%c",S[i]);
	}
}

int Index_KMP(SString *S,SString *T,int pos)
{
	int i=pos,j=1,*next;
	if (1>pos||pos>(*S)[0])
	{
		exit(OVERFLOW);
	}
	if (!(next=(int*)malloc((*T)[0]*sizeof(int))))
	{
		exit(OVERFLOW);
	}
	get_next(T,next);
	while(i<=(*S)[0]&&j<=(*T)[0])
	{
		if((*S)[i]==(*T)[j]||0==j)
		{
			++i;
			++j;
		}
		else
		{
			j=next[j];
		}
	}
	return j>(*T)[0]?i-(*T)[0]:0;
}

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


[3]KMP匹配模式的get_next函数改进

//-----头文件------
#include<stdio.h>
#include<stdlib.h>

//------宏定义------
#define MAXSTRLEN 255
#define OVERFLOW -2
#define TURE 1
#define ERROR 0

//-------类型名替换--------
typedef unsigned char SString[MAXSTRLEN+1];
typedef int Bool;

//-----函数列表-----
Bool StrAssign(SString *T,char *s);
int Index_KMP(SString *S,SString *T,int pos);
void get_nextval(SString *T,int nextval[]);
void StrOutput(SString S);

//-----主函数做替换测试------
void main()
{
	SString t,*T=&t,s,*S=&s;
	int i;
	StrAssign(T,"abaabcac");
	StrAssign(S,"acabaabaabcacaabc");
	i=Index_KMP(S,T,1);
	printf("主串:");
	StrOutput(s);
	printf("\n子串:");
	StrOutput(t);
	printf("\n子串在主串的位置:%d\n",i);
	getchar();
	getchar();
}

//------生成一个其值等于字符串常量的串T------
Bool StrAssign(SString *T,char *s)
{
	int i;
	for(i=0;'\0'!=*s;s++,i++)
	{
		(*T)[i+1]=*s;
	}
	(*T)[0]=i;
	return TURE;
}



//-----输出串-----
void StrOutput(SString S)
{
	int i;
	for(i=1;i<=S[0];i++)
	{
		printf("%c",S[i]);
	}
}

int Index_KMP(SString *S,SString *T,int pos)
{
	int i=pos,j=1,*nextval;
	if (1>pos||pos>(*S)[0])
	{
		exit(OVERFLOW);
	}
	if (!(nextval=(int*)malloc(((*T)[0]+1)*sizeof(int))))
	{
		exit(OVERFLOW);
	}
	get_nextval(T,nextval);
	while(i<=(*S)[0]&&j<=(*T)[0])
	{
		if((*S)[i]==(*T)[j]||0==j)
		{
			++i;
			++j;
		}
		else
		{
			j=nextval[j];
		}
	}
	return j>(*T)[0]?i-(*T)[0]:0;
}

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




 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值