模式匹配:
1. 基本思想:
这种算法是D.E.Knuth 与V.R.Pratt和J.H.Morris同时发现的,因此人们称为KMP算法。此算法可以在O(n+m)的时间数量级上完成串的模式匹配操作。
其基本思想是:每当匹配过程中出现字符串比较不等时,不需回溯i指针,而是利用已经得到的“部分匹配”结果将模式向右“滑动”尽可能远的一段距离后,继续进行比较。
假设主串为“s1s2,...sn",模式串为”p1p2...pn",当主串中第i个字符与模式串中第j个字符“失配”(比较不等)时,主串第i字符(i指针不回溯)应与模式中哪个字符再比较?
令当s[i]!=p[j]时,s[i]应与p[next[j]]进行比较。
例如: P="abaabcac"
则
2.程序:
//**************************************************************************
//模式匹配(KMP)程序
//**************************************************************************
#include "iostream.h"
#include "string.h"
#include "stdio.h"
void get_next(char *T,int *next) //获取模式串右滑值next[i]
{
unsigned int i=1,j=0;
next[1]=0;
while(i<strlen(T)-1)
{
if(j==0||T[i]==T[j])
{
++i;
++j;
next[i]=j;
}
else j=next[j];
}
}
int Index_KMP(char *S,char *T,int pos,int *next)
{
int i=pos,j=1,lenS=strlen(S)-1,lenT=strlen(T)-1; //1=<pos<=strlen(S)-1;
while(i<=lenS&&j<=lenT)
{ if(j==0||S[i]==T[j])
{++i;
++j;
}
else j=next[j];
}
if(j>lenT) return (i-lenT);
else return 0;
}
void main()
{
char S[256], T[20];
int next[20],pos,w;
unsigned int i;
cout<<"输入主串(不包括首字符):"<<endl;
scanf("%s",S);
cout<<"输入模式串(不包括首字符):"<<endl;
scanf("%s",T);
cout<<"输入主串匹配起始位置(在1到"<<strlen(S)-1<<")之间:";
cin>>pos;
get_next(T,next);
w=Index_KMP( S, T, pos, next);
if(w==0)cout<<"匹配不成功!"<<'/n';
else cout<<"匹配成功,从主串第"<<w<<"处找到匹配串"<<endl;
}