AC自动机。
学习链接:
AC自动机算法
KMP算法&AC自动机
代码君
#include <iostream>
#include <algorithm>
#include <cstring>
#include <queue>
#include <string>
#include <cstdio>
using namespace std;
vector<int>ans;
struct node
{
int coun;
node *fail;
node *next[130];
node(){
coun=0;
fail=NULL;
memset(next,0,sizeof(next));
}
};
class Trie
{
private:
node *root;
public:
Trie(){
root=new node();
}
~Trie(){
del(root);
}
void del(node *p){
if(p==NULL)return;
for(int i=0;i<130;i++)del(p->next[i]);
delete p;
}
void insert(string s,int x){
node *p=root;
int len=s.length();
for(int i=0;i<len;i++){
int id=s[i]-31;
if(p->next[id]==NULL){
p->next[id]=new node();
}
p=p->next[id];
}
p->coun=x;
}
void build(){
queue<node*>Q;
Q.push(root);
while(!Q.empty()){
node *p=Q.front();
Q.pop();
for(int i=0;i<130;i++){
if(p->next[i]!=NULL){
if(p==root)p->next[i]->fail=root;
else{
node *tmp=p->fail;
while(tmp!=root&&tmp->next[i]==NULL)tmp=tmp->fail;
tmp=tmp->next[i];
if(tmp==NULL)tmp=root;
p->next[i]->fail=tmp;
}
Q.push(p->next[i]);
}
}
}
}
void query(string s){
node *p=root;
int len=s.length();
for(int i=0;i<len;i++){
int id=s[i]-31;
while(p!=root && p->next[id]==NULL)p=p->fail;
p=p->next[id];
if(p==NULL)p=root;
node *tmp=p;
while(tmp!=root){
if(tmp->coun>=0){
// ans+=tmp->coun;
if(tmp->coun>0)ans.push_back(tmp->coun);
// tmp->coun=-1;
}else break;
tmp=tmp->fail;
}
}
}
};
int main(){
int T;
int n,n1;
while(cin>>n){
string s;
Trie *ac=new Trie();
for(int i=0;i<n;i++){
cin>>s;
ac->insert(s,i+1);
}
ac->build();
scanf("%d",&n1);
int tot=0;
for(int i=0;i<n1;i++){
cin>>s;
ans.clear();
ac->query(s);
if(ans.size()>0){
printf("web %d:",i+1);
sort(ans.begin(),ans.end());
int t=unique(ans.begin(),ans.end())-ans.begin();
for(int i=0;i<t;i++)printf(" %d",ans[i]);
printf("\n");
tot+=ans.size()>0;
}
}
printf("total: %d\n",tot);
}
return 0;
}