题目链接:POJ 3461
题意:字符串匹配。
题解:KMP。有一篇讲解KMP的博客非常详细:从头到尾彻底理解KMP(2014年8月22日版)
我保存了一份PDF
代码:
#include <cstdio>
#include <iostream>
#include <algorithm>
#include <cstring>
#include <string>
using namespace std;
const int MAX=10000+10;
int next[MAX];
void buildNext(string P)
{
int m=P.size();
next[0]=-1;
int i=0,j=-1;
while(i<m)
{
if(j<0||P[i]==P[j])
{
i++;j++;
next[i]=P[i]!=P[j]?j:next[j];//next数组优化
}
else
{
j=next[j];
}
}
}
int KMP(string T,string P)
{
int cnt=0;
buildNext(P);
int n=T.size(),i=0;//原串
int m=P.size(),j=0;//模式串
while(i<n&&j<m)
{
if(j<0||T[i]==P[j])
{
i++;j++;
}
else
{
j=next[j];
}
if(j==m)
{
//如需记录每个匹配成功的位置,可以用一个数组来记录
cnt++;//数量加1
j=next[j];//继续进行多次匹配
}
}
//若只求一次匹配的位置
// if(j==m)
// return i-j;//返回匹配成功的起始位置
// else
// return -1;
return cnt;
}
int main()
{
int T;
scanf("%d",&T);
getchar();
while(T--)
{
string T;
string P;
getline(cin,P);
getline(cin,T);
cout<<KMP(T,P)<<endl;
}
}