1 #include <cstdio> 2 #include <queue> 3 #include <cstring> 4 5 using namespace std; 6 7 struct node { 8 int w, fail, son[26]; 9 } T[3000000]; 10 11 char str[55], AC[1000005]; 12 int rt = 1, TrieCnt = 1; 13 queue<int> Q; 14 15 void Extend() 16 { 17 int p = rt, len = strlen(str+1); 18 for (int i = 1; i <= len; ++i) { 19 int &son = T[p].son[str[i]-'a']; 20 if (!son) son = ++TrieCnt; 21 p = son; 22 } 23 T[p].w = 1; 24 return; 25 } 26 27 void Init() 28 { 29 while (!Q.empty()) Q.pop(); 30 Q.push(rt), T[rt].fail = rt; 31 while (!Q.empty()) { 32 int p = Q.front(); Q.pop(); 33 for (int i = 0; i < 26; ++i) { 34 if (!T[p].son[i]) continue; 35 int son = T[p].son[i], j; 36 Q.push(son); 37 if (p == rt) { T[son].fail = rt; continue; } 38 for (j = T[p].fail; j != rt && !T[j].son[i]; j = T[j].fail); 39 T[son].fail = T[j].son[i] ? T[j].son[i] : rt; 40 } 41 } 42 return; 43 } 44 45 int Query() 46 { 47 int j = rt, len = strlen(AC+1), ans = 0; 48 for (int i = 1; i <= len; ++i) { 49 while (!T[j].son[AC[i]-'a'] && j != rt) j = T[j].fail; 50 if (!T[j].son[AC[i]-'a']) continue; 51 j = T[j].son[AC[i]-'a']; 52 for (int p = j; p != rt && T[p].w != -1; p = T[p].fail) { 53 if (T[p].w == 1) ++ans; 54 T[p].w = -1; 55 } 56 } 57 return ans; 58 } 59 60 int main() 61 { 62 int T; 63 scanf("%d", &T); 64 while (T--) 65 scanf("%s", str+1), Extend(); 66 Init(); 67 scanf("%s", AC+1); 68 printf("%d\n", Query()); 69 return 0; 70 }
NKOJ1960
P1960【自动机】关键词搜索 | |
|
问题描述
如今,搜索引擎像Google,Baidu等搜索引擎已经成为了人们生活的一部分。
韦斯利也想把这个搜索功能加入到他的图片检索系统中。
每张图片都有一个很长的相关描述,当用户们输入了一些关键词去查找图片,韦斯利的系统将会找出与用户输入的关键词匹配数最多的图片并把他显示给用户。
简单的说,给出一段描述图片的文字,再给你一些关键词,你要回答这段文字中匹配了多少个关键词。
输入格式
第一行一个整数n,表示有n个关键词(n<=10000)
接下来n行,每行表示一个关键词,每个关键词由小写字母构成,且长度不超过50
最后一行,表示描述图片的文字,由小写字母构成且长度不超过1000000
输出格式
一个整数,表示最多匹配的关键词数
样例输入
5
she
he
say
shr
her
yasherhs
样例输出
3