• 博客园logo
  • 会员
  • 众包
  • 新闻
  • 博问
  • 闪存
  • 赞助商
  • HarmonyOS
  • Chat2DB
    • 搜索
      所有博客
    • 搜索
      当前博客
  • 写随笔 我的博客 短消息 简洁模式
    用户头像
    我的博客 我的园子 账号设置 会员中心 简洁模式 ... 退出登录
    注册 登录

wchenfeng

  • 博客园
  • 联系
  • 订阅
  • 管理

公告

View Post

实现顺序串的各种模式匹配算法

函数操作

  1. 采用简单匹配算法求子串t在主串s中的位置
  2. 采用KMP算法求子串t在主串s中的位置
  3. 采用改进的KMP算法求子串t在主串s中的位置

 

代码实现

#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#define MaxSize 100
typedef int Status;

typedef struct
{
	char data[MaxSize];
	int length;
}HString;

Status StrAssign(HString &T,char *chars);//生成一个其值等于串常量chars的串T
int StrLength(HString S);//返回S的元素个数,称为串的长度
int StrCompare(HString S, HString T);//若S>T,则返回值>0;若S=T,则返回值=0;若S<T则返回值<0
Status ClearString(HString &S);//将S清空
Status Concat(HString &T, HString S1, HString S2);//用T返回由S1和S2联接而成的新串
Status SubString(HString &Sub, HString S, int pos, int len);
//用Sub返回串S的第pos个字符起长度为len的子串。
int Index_BF(HString S, HString T, int pos);//朴素模式匹配算法
// 返回子串T在主串S中第pos个字符之后的位置,若不存在,则函数值为0。
Status StrInsert(HString &S,int pos,HString T);//在串S的第pos个字符之前插入串T。
Status StrDelete(HString &S,int pos,int len);//从串S中删除第pos个字符起长度为len的子串
void DispStr(HString s);
void GetNextval(HString t,int nextval[]);//求出nextval值
int KMPIndex1(HString s,HString t);//修正的KMP算法

Status StrAssign(HString &T,char *chars)//生成一个其值等于串常量chars的串T
{
	int i=0;
	for(;chars[i]!='\0';i++)
	{
		T.data[i]=chars[i];
	}
	T.length=i;
	return true;
}

int StrLength(HString S)//返回S的元素个数,称为串的长度
{
	return S.length;
}

int StrCompare(HString S, HString T)//若S>T,则返回值>0;若S=T,则返回值=0;若S<T则返回值<0
{
	return S.length-T.length;
}

Status ClearString(HString &S)//将S清空
{
	S.length=0;return true;
}

Status Concat(HString &T, HString S1, HString S2)//用T返回由S1和S2联接而成的新串
{
	int i=0,j=0;
	for(;i<S1.length;i++)
		T.data[i]=S1.data[i];
	for(j=0;j<S2.length;j++)
		T.data[i+j]=S2.data[j];
	T.length=S1.length+S2.length;
	return true;
}

Status SubString(HString &Sub, HString S, int pos, int len)//用Sub返回串S的第pos个字符起长度为len的子串
{
	int i,j=0;
	for(i=pos-1;i<pos+len-1;i++,j++)
		Sub.data[j]=S.data[i];
	Sub.length=len;
	return true;
}

int Index_BF(HString S, HString T, int pos)//朴素模式匹配算法
// 返回子串T在主串S中第pos个字符之后的位置,若不存在,则函数值为0。
{
	int i,j,sum=0;
	for(i=pos;i<S.length;i++)
		{
			sum=0;
			for(j=0;j<T.length;j++)
		{
			if(S.data[i+j]!=T.data[j])
				break;
			if(S.data[i+j]==T.data[j])
				sum++;
			if(sum>=T.length)
				return i+1;//返回主串的匹配首字符的位置
		}
	}
	return 0;
}

int Index_BF(HString S, HString T)//朴素模式匹配算法
// 返回子串T在主串S中的位置,若不存在,则函数值为0。
{
	int i,j,sum=0;
	for(i=0;i<S.length;i++)
	{
		    sum=0;
			for(j=0;j<T.length;j++)
		{
			if(S.data[i+j]!=T.data[j])
				break;
			if(S.data[i+j]==T.data[j])
				sum++;
		}
		if(sum>=T.length)
				return i+1;//返回主串的匹配首字符的位置
	}
	return 0;
}

Status StrInsert(HString &S,int pos,HString T)//在串S的第pos个字符之前插入串T。
{
	int j;
	HString str;
	str.length=0;
	if(pos<=0||pos>S.length+1) return 0;//参数不正确,返回空串
	for(j=0;j<pos-1;j++)//将S.data[0...i-2]复制到str
		str.data[j]=S.data[j];
	for(j=0;j<T.length;j++)//将S.data[0....s2.length-1]复制到str
		str.data[pos+j-1]=T.data[j];
	for(j=pos-1;j<S.length;j++)//将S.data[i-1...s1.length-1]复制到str
		str.data[T.length+j]=S.data[j];
	str.length=S.length+T.length;
	S=str;
	return 1;
}
Status StrDelete(HString &S,int pos,int len)//从串S中删除第pos个字符起长度为len的子串
{
	int i;
	HString str;
	for(i=0;i<pos-1;i++)
		str.data[i]=S.data[i];
	for(;i<S.length-len;i++)
		str.data[i]=S.data[i+len];
	str.length=S.length-len;
	S=str;
	return true;
}

void DispStr(HString s)
{
	int i;
	if(s.length>0)
	{
		for(i=0;i<s.length;i++)
			printf("%c",s.data[i]);
		printf("\n");
	}
}

void GetNext(HString 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(HString s,HString 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+1);//返回主串的匹配首字符的位置
	else
		return (-1);
}

void GetNextval(HString t,int nextval[])
{//求出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(HString s,HString 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+1);
	else
		return (-1);
}
int main()
{
	HString S,T,Sub;
	StrAssign(S,"abcdefgcdeklmnopqrstuvwxyz");//创造一个主串
	printf("S:");
	DispStr(S);
	printf("S串的长度为%d\n",StrLength(S));
	StrAssign(T,"cde");//创造一个模式串
	printf("T:");
	DispStr(T);
	printf("使用BF算法\n");
	printf("Index_BF(S,T)>>返回子串T在主串S中的位置,位置为%d\n",Index_BF(S,T));// 返回子串T在主串sS中的位置,若不存在,则函数值为0
	printf("使用BF算法\n");
	printf("Index_BF(S,T,4)>>返回子串T在主串S中第pos个字符之后的位置,在主串中的位置为%d\n",Index_BF(S,T,4));// 返回子串T在主串sS中第pos个字符之后的位置,若不存在,则函数值为0
	printf("使用KMF算法\n");
	printf("KMPIndex(S,T)>>返回子串T在主串S中的位置,位置为%d\n",KMPIndex(S,T));
	printf("使用改进的KMP算法\n");
	printf("KMPIndex1(S,T)>>返回子串T在主串S中的位置,位置为%d\n",KMPIndex1(S,T));
}

 

输出

 

posted on 2022-04-12 20:02  王陈锋  阅读(116)  评论(0)    收藏  举报

刷新页面返回顶部
 
博客园  ©  2004-2025
浙公网安备 33010602011771号 浙ICP备2021040463号-3