KMP算法
思想
朴素的匹配算法是一对一的匹配,每次匹配失败主串和模式串上的指针都回退到开头,
但实际上这种回退是没有必要的
而KMP算法通过对模式串的处理进而减少回退次数
时间复杂度T=O(n+m)
实现
typedef int Position;
#define NotFound -1
void BuildMatch(Position match[],char *pattern,int len)
{
match[0]=-1;
for(Position j=1;j<len;j++)
{
Position i=match[j-1];
while(i>=0&&pattern[j]!=pattern[i+1])
i=match[i];
if ( pattern[i+1]==pattern[j] )
match[j] = i+1;
else match[j] = -1;
}
}
Position KMP(char *str,char *pattern)
{
int n=strlen(str),m=strlen(pattern);
Position p=0,s=0;
if(n<m)return NotFound;
Position *match=(Position*)malloc(sizeof(Position)*m);
BuildMatch(match,pattern,m);
while(p<m&&s<n)
{
if(str[s]==pattern[p])
{
s++;p++;
}
else if(p>0)
p=match[p-1]+1;
else s++;
}
return p==m?s-m:NotFound;
}
##PTA习题
#include<bits/stdc++.h>
using namespace std;
typedef int Position;
#define NotFound -1
void BuildMatch(Position match[],char *pattern,int len)
{
match[0]=-1;
for(Position j=1;j<len;j++)
{
Position i=match[j-1];
while(i>=0&&pattern[j]!=pattern[i+1])
i=match[i];
if ( pattern[i+1]==pattern[j] )
match[j] = i+1;
else match[j] = -1;
}
}
Position KMP(char *str,char *pattern)
{
int n=strlen(str),m=strlen(pattern);
Position p=0,s=0;
if(n<m)return NotFound;
Position *match=(Position*)malloc(sizeof(Position)*m);
BuildMatch(match,pattern,m);
while(p<m&&s<n)
{
if(str[s]==pattern[p])
{
s++;p++;
}
else if(p>0)
p=match[p-1]+1;
else s++;
}
return p==m?s-m:NotFound;
}
int main()
{
char str[1000001];
scanf("%s",str);
int n;
cin>>n;
for(int i=0;i<n;i++)
{
getchar();
char tmp[100001];
scanf("%s",tmp);
Position p=KMP(str,tmp);
if(p==-1)
cout<<"Not Found\n";
else printf("%s\n",str+p);
}
return 0;
}
参考浙江大学数据结构MOOC