C++基于顺序串的KMP算法实现

#include <iostream>
const int  MAXSIZE=100 ;
using namespace std;

typedef struct{
	char data[MAXSIZE];
	int length;
}SqString;

void StrAssign(SqString &s,char cstr[])
{
	int i=0;
	for(;cstr[i]!=0;i++)
	{
		s.data[i]=cstr[i];
	}
	s.length=i;
}

void DestroyStr(SqString &s)
{
	
}

void StrCopy(SqString &s,SqString t)
{
	s.length=t.length;
	for(int i=0;i<s.length;i++)
	s.data[i]=t.data[i];
}

bool StrEqual(SqString s,SqString t)
{
	if(s.length!=t.length)
	return false;
	else
	{
		for(int i=0;i<t.length;i++)
		{
			if(s.data[i]!=t.data[i])
			{
				return false;
				break;
			}
		}
		return true;
	}
}

int StrLength(SqString s)
{
	return s.length;
}

SqString Concat(SqString s,SqString t)
{
	SqString s1;
	int i=s.length;
	int j=t.length;
	for(int k=0;k<i+j;k++)
	{
		if(k<i)
		s1.data[k]=s.data[k];
		else
		s1.data[k]=t.data[k-i];
	}
	s1.length=i+j;
	return s1;
}

SqString SubStr(SqString s,int i,int j)
{
	SqString s1;
	if(i<0||j>s.length)
	return s1;
	int m=0;
	for(int k=i-1;k<j;k++)
	s1.data[m++]=s.data[k];
	s1.length=j-i+1;
	return s1;
}

SqString InsStr(SqString s1,int i,SqString s2)//a b (qwer)c d e f g  qwer
{
	SqString s;
	int num=0;
	if(i<0||i>s1.length)
	return s;
	else
	{
		s.length=s1.length+s2.length;
		for(int k=0;k<s.length;k++)
		{
			if(k<i-1)
			{
		        s.data[k]=s1.data[k];
				//cout<<k<<endl;
			}
			else if(k>=i-1&&k<s2.length+i-1)
			{
				s.data[k]=s2.data[num++];
				//cout<<k<<endl;
			}
			else if(k<s.length&&k>=s2.length+i-1)
			{
			     s.data[k]=s1.data[k-s2.length];
			     //cout<<k<<endl;
			}
		}
	}
	return s;
}

SqString DelStr(SqString s,int i,int j)//q w e r t
{
	SqString s1;
	if(i<0||j>s.length)
	return s1;
	for(int k=0;k<s.length-(j-i);k++)
	{
		if(k<i-1)
			s1.data[k]=s.data[k];
		else
		{
			s1.data[k]=s.data[j++];
		}
	}
	s1.length=s.length-(j-i);
	return s1;
}

SqString RepStr(SqString s,int i,int j,SqString t)
{
	int m=0;
	SqString s1=s;
	for(int k=i-1;k<j;k++)
	{
		s1.data[k]=t.data[m++];
	}
	return s1;
}

void DispStr(SqString s)
{
	cout<<"串的值为:"<<endl;
	for(int i=0;i<s.length;i++)
	cout<<s.data[i]<<endl;
}

void GetNextval(SqString t,int 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];
	}
}

//KMP算法
int KMP(SqString s,SqString t)
{
	//主串为s,模式串为t
	int nextval[100],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()
{
	char ch[]={"abcdefghijk"};
	char ah[]={"qwert"};
	char aa[]={"abcaabbabcabaacbaacbacba"};
	char bb[]={"abcabaa"};
	SqString s;
	SqString t;
	SqString m;
	SqString z;
	SqString q;
	SqString n;
	SqString w;
	SqString p;
	StrAssign(s,ch);
	cout<<"串的长度为:"<<endl;
	cout<<StrLength(s)<<endl;
	StrCopy(m,s);
	cout<<"复制后的m为:"<<endl;
	DispStr(m);
	StrAssign(t,ah);
	cout<<"赋值后的t为:"<<endl;
	DispStr(t);
	if(StrEqual(s,t))
	cout<<"s串与t串相等噢"<<endl;
	else
	cout<<"s串与t串不相等噢"<<endl;
	z=Concat(s,t);
	cout<<"将s串与t串连接后的样子为:"<<endl;
	DispStr(z);
	q=SubStr(t,1,4);
	cout<<"t串1~4长度上的子串为:"<<endl;
	DispStr(q);
	cout<<"将s删除2~10上的元素后为:"<<endl;
	n=DelStr(s,2,10);
	DispStr(n);
	cout<<"将s的1~5位置用t串将其替换:"<<endl;
	w=RepStr(s,1,5,t);
	DispStr(w);
	cout<<"在s的3号位置插入t串:"<<endl;
	p=InsStr(s,3,t);

	DispStr(p);
	
//以下为KMP算法匹配
   StrAssign(s,aa);
   StrAssign(t,bb);
   DispStr(s);
   DispStr(t);
   if(KMP(s,t))
   cout<<"模式串t在s第"<<KMP(s,t)<<"个位置匹配上"<<endl;
   else
   cout<<"匹配失败!"<<endl;
   
   
	DestroyStr(s);
	DestroyStr(t);
	DestroyStr(m);
	//...
	return 0;
}

  • 3
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

七月是你的谎言..

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值