一、failture版
int pmatch(char *string,char *pat)
{
int i=0,j=0;
int lens=strlen(string);//主字符串
int lenp=strlen(pat);//需要匹配的字符串
while(i < lens && j < lenp)
{
if(string[i]==pat[j])//如果顺利匹配,下标都移动
{
i++;
j++;
}
else if(j==0)//如果需要匹配的字符串首字母都不匹配,主串移动下标
i++;
else //都不是的情况
j=failure[j-1]+1;
}
return ((j==lenp) ? (i-lenp):-1);//返回的是主串匹配的首元素下标
}
void fail(char *pat)
{
int n=strlen(pat);
failure[0]=-1;
int i,j;
for( j=1;j<n;j++)
{
i=failure[j-1];
while((pat[j]!=pat[i+1]) && (i >= 0))//检测需要匹配的串是否有重复的部分
i = failure[i];
if(pat[j] == pat[i+1])//如果有重复,记住位置,当匹配出错,就将需要匹配字符串的下标移动到前面重复出现的字母的下标(下面的例子)
failure[j] = i+1;
else
failure[j] = -1;
}
}
a b c a b c a c a b
failture -1 -1 -1 0 1 2 3 -1 0 1
二、nextval版(kmp改进)
#include<stdio.h>
#include<string.h>
void get_nextval(char *T,int *nextval)
{
int i,j;
i=1;
j=0;
nextval[0]=0;
while(i<strlen(T))
{
if(j==0|| T[i]==T[j])
{
if(T[i]!=T[j])//和未改进算法一样
nextval[i]=j;
else
nextval[i]=nextval[j];//改进就是把之前出现过的都表示一个地方
++i;
++j;
}
else
j=nextval[j];
}
}
int Index_KMP(char *S,char *T,int pos)
{
int i=pos;//可以实现任意开始位置匹配
int j=0;
int len1=strlen(S);
int len2=strlen(T);
int next[255]={0};
get_nextval(T,next);
while(i<len1&&j<len2)
{
if(j==0||S[i]==T[j])
{
++i;
++j;
}
else
j=next[j];
}
if(j>=len2)
return i-len2;
else
return -1;
}
int main()
{
char *a="aaabbaaabbb";
char *b="aaabbb";
printf("%d\n",Index_KMP(a,b,0));//从头开始匹配
return 0;
}