KMP模式匹配算法(C++)


/*
 *通过计算返回子串的next数组
 */

void Get_Next(string s,int *next)
{

	int i,j,len;
	i=1;
	j=0;

	len=s.length();//此处str.length()表示串长度
	next[0] =0;

	while(i<len)
	{

		
		if (j==0 || s[i-1]==s[j-1])//s[j-1]表示前缀的单个字符,s[i-1]表示后缀的单个字符
		{
			++j;
			++i;
			next[i-1] =j;
		}
		else
			j=next[j-1 ];    //若字符不相同,则j回溯*/ 

	}



}

/*
 *优化改进后的next函数
 *通过计算返回子串的next数组
 */

void Get_NextVal(string s,int *next)
{

	int i,j,len;
	i=1;
	j=0;

	len=s.length();//此处str.length()表示串长度
	next[0] =0;

	while(i<len)
	{

		
		if (j==0 || s[i-1]==s[j-1])//s[j-1]表示前缀的单个字符,s[i-1]表示后缀的单个字符
		{
			++j;
			++i;

			if (s[i-1]!=s[j-1])/*若当前字符与前缀字符不同*/
			   next[i-1] =j;   /*则当前的j为next在i位置的值*/
			else
               next[i-1] =next[j-1];/*与前缀字符相同*/   
			                        /*字符的next值赋值给next在i-1位置的值*/
		}
		else
			j=next[j-1 ];    //若字符不相同,则i回溯*/ 

	}



}

测试函数

void main(void)
{ 

	string t;
	t="ababaaaba";//测试字符串

	int len;
	len=t.length();

	int *p=new int[len];

	Get_Next(t,p);//测试Get_Next函数

	cout<<"Get_Next函数得到next数组值:";
	for (int i=0;i<	len;i++)
			cout<<p[i];
	cout<<endl;

	Get_NextVal(t,p);//测试Get_NextVal函数
	cout<<"Get_NextVal函数得到next数组值:";
	for (int i=0;i<	len;i++)
		cout<<p[i];
	cout<<endl;

	delete [] p;
	system("pause");
}
输出结果


/*
 * 返回子串t在主串s位置,若不存在返回-1
 * t非空,
 */
int Index_KMP(string s,string t, int pos)
{
	
	int i=pos;//i用于主串s当前位置下标0~s.length()-1
	int j=0;//j用于子串t当前位置下标从0开始

	int next[255];//定义一next数组
	Get_NextVal(t,next);//获取子串t的next数组

	int sLen=s.length();//主串长度
	int tLen=t.length();//子串长度
	while(i<=sLen && j<=tLen)
	{
		if (j==0 || s[i-1]==t[j-1])//字母相等继续
		{
			++i;
			++j;
		}
		else
		{
			j=next[j-1];//j退回适合位置i不变
		}

	}


	if (j>tLen)
	return i-tLen-1;

	return -1;
}

测试函数

void main(void)
{ 
	string s,t1,t2;
	s="aaaabcde";
	t1="aaaaax";
	t2="de";

	int x=Index_KMP( s, t1, 0);//索引位置从0开始
	if (x==-1)
	cout<<"t1不在s中"<<endl;
	else
	cout<<"t1在s中位置是"<<x<<endl;

	
    x=Index_KMP( s, t2, 0);
	if (x==-1)
		cout<<"t2不在s中"<<endl;
	else
		cout<<"t2在s中位置是"<<x<<endl;

	system("pause");
}

输出结果



参考文献:

  《 大话数据结构 》--程 杰    下载地址大话数据结构

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值