关键词匹配(Ac自动机模板题)
2772: 关键词匹配
Time Limit: 1 Sec Memory Limit: 128 MBSubmit: 10 Solved: 4
[Submit][Status][Web Board]
Description
给你N个单词,然后给定一个字符串,问一共有多少单词在这个字符串中出现过(输入相同的字符串算不同的单词,同一个单词重复出现只计一次)。
Input
第一行一个整数N,表示给定单词的个数。
接下来N行,每行输入一个长度不超过50且全由小写字母组成的单词。
最后一行输入一个长度不超过1000000的字符串。
N≤10000
接下来N行,每行输入一个长度不超过50且全由小写字母组成的单词。
最后一行输入一个长度不超过1000000的字符串。
N≤10000
Output
输出一行包含一个整数,表示共在给定字符串中出现过的单词个数。
Sample Input
5
she
he
say
shr
her
yasherhs
Sample Output
3
HINT
Source
题解:
裸Ac自动机,不会的可以去看看这个博客:http://www.cppblog.com/menjitianya/archive/2014/07/10/207604.html;
1 #include<iostream> 2 #include<cstring> 3 #include<cstdio> 4 #define maxn 1000005 5 #define maxm 1000005 6 using namespace std; 7 int n,tot,head,tail,son[maxm][26],fai[maxm],sum[maxm],list[maxm]; 8 char s[maxn]; 9 void clear(){ 10 tot=0; 11 memset(son,0,sizeof(son)); 12 memset(sum,0,sizeof(sum)); 13 } 14 void insert(char *s){ 15 int p=0; 16 for (int i=1;s[i];p=son[p][s[i]-'a'],i++) if (!son[p][s[i]-'a']) son[p][s[i]-'a']=++tot; 17 sum[p]++; 18 } 19 void failed(){ 20 head=0,tail=1,list[1]=0,fai[0]=-1; 21 while (head!=tail){ 22 int x=list[++head]; 23 for (int ch=0;ch<26;ch++) 24 if (son[x][ch]){ 25 list[++tail]=son[x][ch]; 26 int p=fai[x]; 27 while (p!=-1&&!son[p][ch]) p=fai[p]; 28 if (p==-1) fai[son[x][ch]]=0; 29 else fai[son[x][ch]]=son[p][ch]; 30 } 31 } 32 } 33 void work(char *s){ 34 int ans=0; 35 for (int i=1,p=0;s[i];i++){ 36 while (p&&!son[p][s[i]-'a']) p=fai[p]; 37 p=son[p][s[i]-'a']; 38 for (int t=p;t;t=fai[t]) ans+=sum[t],sum[t]=0; 39 } 40 printf("%d\n",ans); 41 } 42 int main() 43 { 44 cin>>n;//,clear(); 45 for (int i=1;i<=n;i++) scanf("%s",s+1),insert(s); 46 failed(); 47 scanf("%s",s+1),work(s); 48 return 0; 49 }
我太蒟蒻了,所以神犇们留下意见让我跪膜