题目链接
https://ac.nowcoder.com/acm/contest/7412/G
题目大意
字符串匹配。
解题思路
我的KMP详讲 更新于2020.10.21
一上来就想暴力,明知道暴力不行,还是想试试,毕竟不会别方法了。果不其然,过了80多的数据,没AC。
正解:KMP!(没听说过,百度了一下,发现真的是巨难!用了3h才勉强理解,但是代码还是自己写不出来,背过的)
(我实在讲不明白,直接放弃自己手写)
(教会我KMP的大佬讲解)
就本题而言,无非是把牛牛喜欢的字符串S作为模式串(即由j控制的字符串),多组输入的字符串作为文本串(即由i控制的字符串),同时在KMP函数里统计一下匹配到的最长子串,对应语句为 maxx=max(maxx,j);,理解了KMP实现过程之后会发现j的值为公共子串的长度,所以取j的最大值就是能扫描到的模式串S(即牛牛喜欢的字符串)的最长长度。累加输出。
函数模板
//获取next数组
void getnext(string s){
nxt[0]=-1;//不能用next作为名字,因为c++中存在next
int i=0,j=-1;
int len=s.length();
while(i<len-1){
if(j==-1 || s[i]==s[j]){
++i;
++j;
nxt[i]=j;
}
else j=nxt[j];
}
}
//KMP,只是匹配的过程(根据题目要求进行变形)
void KMP(string s,string p){
int i=0,j=0,maxx=0;
int slen=s.length(),plen=p.length();
while(i<slen && j<plen){
if(j==-1 || s[i]==p[j]){
++i;
++j;
}
else j=nxt[j];
}
}AC代码
#include<bits/stdc++.h>
#define ll long long
using namespace std;
const int N=1e5+10;
int nxt[N];
void getnext(string s){
nxt[0]=-1;
int i=0,j=-1;
int len=s.length();
while(i<len-1){
if(j==-1 || s[i]==s[j]){
++i;
++j;
nxt[i]=j;
}
else j=nxt[j];
}
}
int KMP(string s,string p){
int i=0,j=0,maxx=0;
int slen=s.length(),plen=p.length();
while(i<slen && j<plen){
if(j==-1 || s[i]==p[j]){
++i;
++j;
maxx=max(maxx,j);//唯一变化!关键语句!
}
else j=nxt[j];
}
return maxx;
}
ll ans;
string str,tmpstr;
int n;
int main(){
cin>>str;
getnext(str);
cin>>n;
while(n--){
cin>>tmpstr;
ans+=KMP(tmpstr,str);
}
cout<<ans<<endl;
}优化代码
#include<bits/stdc++.h>
using namespace std;
const int N=1e5+100;
int nxt[N];
/*
void CreateNext(string p){
nxt[1]=0;
int i=1,j=0,len=p.size();
p='.'+p;
while(i<=len){
if(j==0 || p[i]==p[j]){
++i,++j;
nxt[i]=j;
}
else j=nxt[j];
}
}
*/
void CreateNext(string p){
nxt[1]=0;
int i=1,j=0,len=p.size();
p='.'+p;
while(i<=len){
if(j==0 || p[i]==p[j]){//通过i去更新nxt里面存储的位置
++i;++j;
if(p[i]==p[j]) nxt[i]=nxt[nxt[i]];//此时nxt[i]=j,因此 <=> nxt[i]=nxt[j];
else nxt[i]=j;
}
else j=nxt[j];
}
}
int Match(string s,string p){
int i=1,j=1,happy=0,slen=s.size(),plen=p.size();
s='.'+s;
p='.'+p;
while(i<=slen && j<=plen){
if(j==0 || s[i]==p[j]) {happy=max(happy,j);++i;++j;}
else j=nxt[j];
}
// cout<<happy<<endl;
return happy;
}
string p,s;
int n,ans;
int main(){
cin>>p>>n;
CreateNext(p);
for(int i=1;i<=n;i++){
cin>>s;
ans+=Match(s,p);
}
cout<<ans<<endl;
} 暴力代码
#include<bits/stdc++.h>
#define ll long long
using namespace std;
vector<string> book;
string tmp_str,like;
int n;
ll ans;
int main(){
cin>>like;
cin>>n;
for(int i=1;i<=n;i++){
cin>>tmp_str;
book.push_back(tmp_str);
}
int vsize=book.size();
int likesize=like.length();
for(int i=0;i<vsize;i++){
int maxx=0;
int booksize=book[i].length();
for(int j=0;j<booksize;j++){
int p2=0,p1=j,cnt=0;
while(p1<booksize && p2<likesize && book[i][p1]==like[p2]) p1++,p2++,cnt++;
maxx=max(cnt,maxx);
}
ans+=maxx;
// cout<<maxx<<endl;
}
cout<<ans<<endl;
} 
京公网安备 11010502036488号