您的位置:首页 > 其它

模式匹配中的kmp算法

2008-10-15 09:39 218 查看
//:kmp
//kmp算法是效率最高的模式匹配算法
//其主要思想是:(假设i,j分别指向主串mStr和模式sStr的当前试匹配位置)当mStr[i]!=mStr[j]时并不
//按传统的回溯i,j ,而是i不变j重一个算好的数组回溯,该数组可使得模式串向右
//移动尽可能多的距离。
//主要原理:假设当i,j失配的时候应该用模式的k字符与主串的j字符进行比较
//则: sStr[1~k-1] = mStr[i-k+1 ~ i-1]
//又已知:sStr[j-k+1 ~ j-1]=mStr[i-k+1 ~ i-1]
//所以: sStr[1~k-1] = sStr[j-k+1 ~ j-1];
//所以可以根据字串计算出每个字符对应的最大k,储存在next[]中,简便方法为:
//1,初始化 next[0] = -1 ,i,j分别代表sStr[0~i-1] = sStr[j-i-1,j-1]情况下的i,j且j+1是当前失配位置
//2,如果sStr[i] == sStr[j] ; 则sStr[0~i] = sStr[j-i-1,j],如果此时sStr[0~i+1] = sStr[j-i-1,j+1]
//则当j+1位置失配时,推到i+1位置也会失配,所以应使next[j+1] = next[i+1]如果sStr[0~i+1] != sStr[j-i-1,j+1]
//则next[j+1]=i+1;
//3,如果j<strlen(sStr)重复2
//4,退出

#include<iostream>
#include<cstdio>
int * getIndex(const char *pstr,int *next)//及时一个串的模式匹配数组
{
next[0]=-1,next[1]=0;

int i = 0,j=1;

while(j < strlen(pstr))
{
if(i == -1 || pstr[i]==pstr[j])
{
//如果i==-1则将模式的第一个字符和主串的下一个字符比较
//如果pstr[i]==pstr[j]比较后续字符
++i,++j;
if(pstr[i] == pstr[j])
{//sStr[0~i] = sStr[j-i-1,j]
next[j] = next[i];
}
else
{//sStr[0~i] != sStr[j-i-1,j]
next[j]=i;
}
}
else
{
i = next[i];
}
}
return next;
}

int kmp(const char * mainSour,const char * subStr,int pos)
{
int res = -1;
int * next = new int[strlen(subStr)];
//计算数组
getIndex(subStr,next);

int i=pos,j=0,end= strlen(subStr);

while(i<end)//未到达主串的尾部
{
if(mainSour[i] == subStr[j] || j == -1)
{
++i,++j;
if(!subStr[j])
{
res = i-strlen(subStr);
break;
}
}
else
{//失配则回溯j
j = next[j];
}
}
return res;
}

int main()
{
std::cout<<kmp("ababcabcacbab","abcac",0)<<std::endl;
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: