先不对next数组计算,KMP的程序算法展开,就先记下手动算的过程,算法到时候再说吧,嗯,就这yang
朴素模式匹配
最坏的时间复杂度O(mn)
int k=1;//主串的下一个往返位置
int i=k;j=1;//主、子串的所在位置
while(主、子串都未结束){
if(相等)
i++,j++;
else(不相等)
k++;
i=k;
j=1;
}
if(j>子串长度)
return i-子串长度;
return 错误;
//因为有可能是因为主串结束而结束的循环
KMP模式匹配
时间复杂度O(m+n)
正常串下标是从1开始,这就正常计算,
如果遇到下标是从0开始的,也先正常计算,然后再整体-1就可以
next[1]=0;
next[2]=1;
找1~j-1的字符最长前后缀匹配长度
next[j]=长度+1;
nextval[1]=0;
从前向后遍历,字符相同的就替换next,不同的就继续向后移动
今天来把他的实现给敲了
#include <iostream>
using namespace std;
#define MAXSIZE 30
typedef struct {
char ch[MAXSIZE];
int length;
}SString;
//普通模式匹配
int Index(SString S,SString T){
int k=1;
int i=k,j=1;
while(i<=S.length&&j<=T.length){
if(S.ch[i]==T.ch[j]){
++i;
++j;
}
else{
k++;
i=k;
j=1;
}
}
if(j>T.length)
return i-T.length;
return 0;
}
//KMP模式匹配
int KMPindex(SString S,SString T,int next[]){
int i=1,j=1;
while(i<=S.length&&j<=T.length){
if(j==0||S.ch[i]==T.ch[j]){
++i;
++j;
}
else{
j=next[j];
}
}
if(j>T.length)
return i-T.length;
return 0;
}
//next[]的求法
void get_next(SString S,int next[]){
next[1]=0;
//next[2]=1;
int i=1,j=0;
while(i<S.length){
if(j==0||S.ch[i]==S.ch[j]){
++i;
++j;
next[i]=j;
//next[j+1]=next[j]+1;
}
else{
j=next[j];
}
}
}