模式匹配最原始的算法是BF算法:
int index_bf(char *s,char *t) { int i,j; i=j=1; while(i<=s[0]&&j<=t[0]) { if(s[i]==t[j]) { i++; j++; } else//主串和模式串都回溯 { i=i-j+2; j=1; } } if(j>t[0])//匹配成功 { return i-t[0]; } else//匹配失败 { return 0; } }
之后就是KMP算法,它是BF算法的一种优化,当主串匹配失败时,不必回溯,只需要将模式串回溯一部分即可,这样就大大节省了时间:
int index_kmp(char *s,char *t) { int i,j; i=j=1; while(i<=s[0]&&j<=t[0]) { if(s[i]==t[j]||j==0) { i++; j++; } else//只要回溯模式串就好 ,j==0表示主串上的第i个字符一直从模式串回溯到0都没找到与主串相等的,所以又要从主串的下个一字符与模式串的第一个开始匹配。 { j=next[j]; } } if(j>t[0]) { return i-t[0]; } else { return 0; } }}
next函数:
void get_next(char *t,int next[]) { int i=1,j=0; next[1]=0; while(i<t[0]) { if(t[i]==t[j]||j==0)//自身又是模式串又是主串,进行匹配,如果,p[k]==p[j] ,继续比较下一个p[j+1] ,next[j+1]=k+1=next[j]+1; { i++; j++; if(t[i]!=t[j])//优化 { next[i]=j; } else { next[i]=next[j]; } } else//不相等回溯。 { j=next[j]; } } }