思路:用KMP和AC思路是一样的。ac的思路就是跑文本串,记录下每个节点的最小值,这样会省时间,因为fail指针的存在,我们不需要管模式串,kmp的话就是每个模式串都要匹配,取最小值;
#include<bits/stdc++.h>
using namespace std;
const int N=1e5+10;
int val[N];
int nxt[500010][26], fail[500010];
stack<int> st;
bool vis[500010];
struct Trie{
int root, L;
int newnode(){
for(int i=0; i<27; i++)
nxt[L][i]=-1;
return L++;
}
void init(){
L=0;
memset(val, 0x3f, sizeof val);
root=newnode();
}
void Insert(char buf[]){
int len=strlen(buf);
int now=root;
val[now]=min(len, val[now]);
for(int i=0; i<len; i++){
if(nxt[now][buf[i]-'a']==-1)
nxt[now][buf[i]-'a']=newnode();
now=nxt[now][buf[i]-'a'];
val[now]=min(val[now], len-i-1);
}
}
void build(){
queue<int>Q;
fail[root]=root;
for(int i=0; i<26; i++)
if(nxt[root][i]==-1)
nxt[root][i]=root;
else{
fail[nxt[root][i]]=root;
Q.push(nxt[root][i]);
}
while(!Q.empty()){
int now=Q.front();
Q.pop();
for(int i=0; i<26; i++)
if(nxt[now][i]==-1)
nxt[now][i]=nxt[fail[now]][i];
else{
fail[nxt[now][i]]=nxt[fail[now]][i];
Q.push(nxt[now][i]);
}
}
}
void query(char buf[]){
int len=strlen(buf);
int now=root;
for(int i=0; i<len; i++){
if(buf[i]=='-'){
if(!st.empty()) st.pop();
if(!st.empty()) now=st.top();
else now=0;
}
else{
now=nxt[now][buf[i]-'a'];
st.push(now);
}
int tmp=now, ans=val[now];
while(tmp!=root&&!vis[tmp]){
tmp=fail[tmp];
ans=min(val[tmp], ans);
vis[tmp]=true;
}
printf("%d\n", ans);
}
}
};
int n;
char s[5][N], txt[N];
int main(){
Trie ac;
ac.init();
scanf("%d", &n);
for(int i=1; i<=n; i++){
scanf("%s", s[i]);
ac.Insert(s[i]);
}
ac.build();
scanf("%s", txt);
printf("%d\n", val[0]);
ac.query(txt);
return 0;
}
#include<bits/stdc++.h>
using namespace std;
const int N=1e5+10;
const int INF=0x3f3f3f3f;
int nxt[5][N], n, length[5], pos[5][N];
char txt[N], s[5][N];
void get_nxt(char str[], int m, int id){
int i, j;
j=nxt[id][0]=-1; i=0;
while(i<m){
while(-1!=j && str[i]!=str[j]) j=nxt[id][j];
if(str[++i]==str[++j])
nxt[id][i]=nxt[id][j];
else
nxt[id][i]=j;
}
}
int main(){
scanf("%d", &n);
for(int i=1; i<=n; i++){
scanf("%s", s[i]);
length[i]=strlen(s[i]);
get_nxt(s[i], length[i], i);
}
scanf("%s", txt);
int mn=INF;
for(int i=1; i<=n; i++) mn=min(length[i], mn);
printf("%d\n", mn);
int len=strlen(txt), id=0;
for(int i=0; i<len; i++){
if(txt[i]=='-'){
if(id) id--;
mn=INF;
for(int j=1; j<=n; j++)
mn=min(mn, length[j]-pos[j][id]);
printf("%d\n", mn);
}
else{
int tmp; mn=INF;
for(int j=1; j<=n; j++){
tmp=pos[j][id];
while(tmp!=-1 && s[j][tmp]!=txt[i]) tmp=nxt[j][tmp];
pos[j][id+1]=++tmp;
mn=min(mn, length[j]-tmp);
}
printf("%d\n", mn);
id++;
}
}
return 0;
}