1、Naive的模式匹配
int NaiveIndex(char * Sstr,char * Tstr)
{
int i=0,j=0;
while(i<strlen(Sstr)&&j<strlen(Tstr))
{
if(Sstr[i]==Tstr[j])
{
i++;
j++;
}
else
{
i=i-j+1; //指针回溯
j=0;
}
}
if(j==strlen(Tstr))
return i-j;
else
return -1;
}
此方法最鲜明的特点就是指针回溯,时间复杂度为O(n*m)。
2、KMP算法
KMP算法中主串指针无须回溯,这是通过分析模式串中所蕴含的信息实现的。
从i=0,j=0看是,判断Sstr[i]==Tstr[j]是否相等
若相等,i++,j++,一直向下匹配;
若不相等,j=next[j],再重新判断Sstr[i]==Tstr[j]是否相等,直至匹配成功或主串遍历完毕
这里的next[j]就是根据模式串中蕴含的信息建立的数组。可以这样理解:在模式串位置j处之前的next[j]个字符与模式串开始的next[j]个字符是匹配的,但不是重叠的。
即模式串中索引值为0~next[j]-1之间的字符与主串中索引值为i-next[j]+1~i之间的字符是匹配的,接下来就要判断Sstr[i]==Tstr[j]是否相等(j=next[j])。
//next[]数组值的求解
void getNext(char *Tstr,int next[])
{
next[0]=-1;
int i=0,j=-1;
while(i<strlen(Tstr))
{
if(j==-1||Tstr[i]==Tstr[j])
{
i++;
j++;
next[i]=j;
}
else
j=next[j];
}
}
//KMPIndex函数
int KMPINdex(char * Sstr,char * Tstr)
{
int i=0,j=0;
int lenS=strlen(Sstr);
int lenT=strlen(Tstr);
while(i<lenS&&j<lenT-1)
{
if(j==-1||Sstr[i]==Sstr[j])
{
i++;
j++;
}
else
j=next[j];
}
if(j==lenS-1)
return i-j;
else
return -1;
}
主串中每个字符只与模式串中的一个字符比较,因此时间复杂度为O(m+n)。