这题被逗死================
<pre name="code" class="cpp">#include <iostream>
#include <cstring>
#include <cstdio>
#include <queue>
using namespace std;
const int N=2000006;
const int maxn=1005;
struct node{
int fail,son[26],id;
bool flag,yes;
}trie[N];
int tot,cnt[maxn];
void init(){
for(int i=0;i<=tot;i++){
trie[i].fail=trie[i].id=trie[i].flag=trie[i].yes=0;
for(int j=0;j<26;j++)
trie[i].son[j]=0;
}
memset(cnt,0,sizeof(cnt));
tot=0;
}
void Insert(char *s,int v){
int p=0;
for(int i=0,len=strlen(s);i<len;i++){
int t=s[i]-'A';
if(!trie[p].son[t])
trie[p].son[t]=++tot;
p=trie[p].son[t];
}
trie[p].yes=true;
trie[p].id=v;
}
void build_ac(){
queue<int> Q;
for(int i=0;i<26;i++)
if(trie[0].son[i])
Q.push(trie[0].son[i]);
while(!Q.empty()){
int u=Q.front();Q.pop();
for(int i=0;i<26;i++){
int t=trie[u].son[i];
if(!t)continue;
int f=trie[u].fail;
while(f && !trie[f].son[i])
f=trie[f].fail;
trie[t].fail=trie[f].son[i];
Q.push(t);
}
}
}
void Query(char *s){
int p=0;
for(int i=0;s[i];i++){
if(s[i] >= 'A' && s[i] <= 'Z'){
int t=s[i]-'A';
while(p && !trie[p].son[t])
p=trie[p].fail;
p=trie[p].son[t];
int tmp=p;
while(tmp && !trie[tmp].flag&&trie[tmp].yes){
cnt[trie[tmp].id]++;
//trie[tmp].flag=true;////////这个是算出现了多少个模式串用的,现在用不上
tmp=trie[tmp].fail;
}
}else p=0;
}
}
char s1[N];int n;
char s[1010][55];
int main(){
while(scanf("%d",&n)==1){
init();
for(int i=1;i<=n;i++){
scanf(" %s",s[i]);
Insert(s[i],i);
}
build_ac();
scanf(" %s",s1);
Query(s1);
for(int i=1;i<=n;i++)
if(cnt[i])
printf("%s: %d\n",s[i],cnt[i]);
}
return 0;
}
本文详细介绍了如何使用AC自动机构建一个自动完成字符串匹配的系统,包括初始化、插入字符串、构建自动机以及查询功能。通过实例代码展示了整个实现过程。
453

被折叠的 条评论
为什么被折叠?



