您的位置:首页 > 其它

KMP算法 NEXT数组的两种形式

2012-12-21 10:01 225 查看
转载自:http://blog.csdn.net/hackbuteer1/article/details/7319115

http://blog.csdn.net/hackbuteer1/article/details/7319115

NEXT数组有两种形式

1. NEXT数组可以找到当前字符之前的字符串的最长非重叠最长子字符串串的长度

2. NEXT数组可以找到从第一个字符到最后一个字符的最长重复最长子字符串的长度

参考一下的代码:

class CKMP
{
public:
explicit CKMP(char* s1,char *p1);
virtual ~CKMP();
public:
void getNext_1();//匹配字符串时候的next 对应1
void getNext_2();//查找最长重复子串时候的Next 对应2
int KMPMatch();
int *getNext(){return next;}
private:
char s[10000];//目标字符串
char p[1000];//模式串
int next[1000];//next数组
};
CKMP::CKMP(char *s1,char *s2)
{
memset(s,0,10000*sizeof(char));
memset(p,0,1000*sizeof(char));
memset(next,0,1000*sizeof(int));
strcpy(s,s1);
strcpy(p,s2);
}
CKMP::~CKMP()
{
}
void CKMP::getNext_1()
{//p为模式串 计算模式串p的next
memset(next,0,sizeof(next));
int j,k;
next[0]=-1;
j=0;
k=-1;
while(j<strlen(p)-1)
{
if(k==-1||p[j]==p[k])
{
k++;
j++;
next[j]=k;
}
else
k=next[k];
}
}
int CKMP::KMPMatch()
{
int i,j;
i=0;j=0;
getNext_1();//计算模式串p的next
while(i<strlen(s))//s为目标串
{
if(j==-1||s[i]==p[j])
{//当j==-1的时候,匹配出错,目标串从右移一位 模式串从头开始匹配
i++;
j++;
}
else
{
j=next[j];
}
if(j==strlen(p))
{//如果模式串p的长度等于j  找到了匹配的字符串
return i-strlen(p);//返回匹配的首地址下标
}
}
return -1;
}
//获得重复字符串的长度next 从i开始到最后一个字符结束的最长重复串,读取next[len]就可以
void CKMP::getNext_2()
{//获得模式串的next数组
memset(next,0,sizeof(next));
int i=0,j=-1;
next[0]=-1;
while(p[i]!='\0')//模式串p
{
if(j==-1||p[i]==p[j])
{
j++;i++;
if(p[i]!=p[j])
next[i]=j;//匹配失败时候 就赋值
else
next[i]=next[j];
}
else
j=next[j];
}
}


运行的截图:

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: