您的位置:首页 > 编程语言 > C语言/C++

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

2014-09-18 16:35 253 查看
/*
*通过计算返回子串的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");
}

输出结果



参考文献:

  《 大话数据结构 》--程 杰    下载地址大话数据结构
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: