KMP模板:
#include<iostream>
using namespace std;
const int MAX_S=1000005;
int n,m;
string str,st;
int Next[MAX_S];
void GetNext();
int KMP();
int main()
{
ios::sync_with_stdio(false);
while(cin>>str>>st){
n=str.size(); m=st.size();
cout<<KMP()<<endl;
}
return 0;
}
void GetNext()
{
int k=-1;
Next[0]=-1;
for(int i=1;i<m;++i)
{
while(k!=-1&&st[k+1]!=st[i]){
k=Next[k]; //下一匹配位置
}
if(st[k+1]==st[i]) ++k;
Next[i]=k;
}
}
int KMP()
{
int ans=-1;
GetNext();
for(int i=0,j=-1;i<n;++i)
{
while(j!=-1&&st[j+1]!=str[i]){
j=Next[j];
}
if(st[j+1]==str[i]) ++j;
if(j==m-1){
// j=-1;//重新寻找匹配,匹配字符串之间不重叠,若匹配字符串之间可重叠则不变
ans=i-j; break;
}
}
//返回匹配首下标,为-1表示匹配失败
return ans;
}
一,求匹配的首下标 HDU-1711-Number Sequence 直接套用模板。。
Code :
#include<iostream>
using namespace std;
const int MAX_S=1000005;
const int MAX_M=10005;
int n,m,T;
int str[MAX_S],st[MAX_M];
int Next[MAX_M];
void GetNext();
int KMP();
int main()
{
ios::sync_with_stdio(false);
cin>>T;
while(T--){
cin>>n>>m;
for(int i=0;i<n;++i)
cin>>str[i];
for(int i=0;i<m;++i)
cin>>st[i];
cout<<KMP()<<endl;
}
return 0;
}
void GetNext()
{
int k=-1;
Next[0]=-1;
for(int i=1;i<m;++i)
{
while(k!=-1&&st[k+1]!=st[i]){
k=Next[k]; //下一匹配位置
}
if(st[k+1]==st[i]) ++k;
Next[i]=k;
}
}
int KMP()
{
int ans=-1;
GetNext();
for(int i=0,j=-1;i<n;++i)
{
while(j!=-1&&st[j+1]!=str[i]){
j=Next[j];
}
if(st[j+1]==str[i]) ++j;
if(j==m-1){
ans=i-j+1; break;
}
}
return ans;
}
二,求匹配次数,匹配字符串之间可重叠 HDU-1686-Oulipo 查找到直接计数即可
Code :
#include<iostream>
using namespace std;
const int MAX_S=10005;
int n,m,T;
string str,st;
int Next[MAX_S];
void GetNext();
int KMP();
int main()
{
ios::sync_with_stdio(false);
cin>>T;
while(T--){
cin>>st>>str;
n=str.size(); m=st.size();
cout<<KMP()<<endl;
}
return 0;
}
void GetNext()
{
int k=-1;
Next[0]=-1;
for(int i=1;i<m;++i)
{
while(k!=-1&&st[k+1]!=st[i]){
k=Next[k];
}
if(st[k+1]==st[i]) ++k;
Next[i]=k;
}
}
int KMP()
{
int ans=0;
GetNext();
for(int i=0,j=-1;i<n;++i)
{
while(j!=-1&&st[j+1]!=str[i]){
j=Next[j];
}
if(st[j+1]==str[i]) ++j;
if(j==m-1) ++ans;
}
return ans;
}
三,求匹配次数,匹配字符串之间不可重叠 HDU-2087-剪花布条 查找到后将 j=-1即可
Code :
#include<iostream>
using namespace std;
const int MAX_S=10005;
int n,m,T;
string str,st;
int Next[MAX_S];
void GetNext();
int KMP();
int main
{
ios::sync_with_stdio(false);
while(cin>>str&&str!="#"){
cin>>st;
n=str.size(); m=st.size();
cout<<KMP()<<endl;
}
return 0;
}
void GetNext()
{
int k=-1;
Next[0]=-1;
for(int i=1;i<m;++i)
{
while(k!=-1&&st[k+1]!=st[i]){
k=Next[k];
}
if(st[k+1]==st[i]) ++k;
Next[i]=k;
}
}
int KMP()
{
int ans=0;
GetNext();
for(int i=0,j=-1;i<n;++i)
{
while(j!=-1&&st[j+1]!=str[i]){
j=Next[j];
}
if(st[j+1]==str[i]) ++j;
if(j==m-1){
j=-1; ++ans;
}
}
return ans;
}
这些只是最基础的KMP模板题,想更深去学习的可以去这篇博客学习 KMP模板以及简单的入门题总结