Keywords Search(AC自动机)
2015-07-26 17:53
295 查看
A - Keywords Search
Time Limit:1000MS Memory Limit:32768KB 64bit IO Format:%I64d
& %I64u
Submit Status
Description
In the modern time, Search engine came into the life of everybody like Google, Baidu, etc.
Wiskey also wants to bring this feature to his image retrieval system.
Every image have a long description, when users type some keywords to find the image, the system will match the keywords with description of image and show the image which the most keywords be matched.
To simplify the problem, giving you a description of image, and some keywords, you should tell me how many keywords will be match.
Input
First line will contain one integer means how many cases will follow by.
Each case will contain two integers N means the number of keywords and N keywords follow. (N <= 10000)
Each keyword will only contains characters 'a'-'z', and the length will be not longer than 50.
The last line is the description, and the length will be not longer than 1000000.
Output
Print how many keywords are contained in the description.
Sample Input
1
5
she
he
say
shr
her
yasherhs
Sample Output
3
bestcode:
AC代码:
注释代码&&模板:
Time Limit:1000MS Memory Limit:32768KB 64bit IO Format:%I64d
& %I64u
Submit Status
Description
In the modern time, Search engine came into the life of everybody like Google, Baidu, etc.
Wiskey also wants to bring this feature to his image retrieval system.
Every image have a long description, when users type some keywords to find the image, the system will match the keywords with description of image and show the image which the most keywords be matched.
To simplify the problem, giving you a description of image, and some keywords, you should tell me how many keywords will be match.
Input
First line will contain one integer means how many cases will follow by.
Each case will contain two integers N means the number of keywords and N keywords follow. (N <= 10000)
Each keyword will only contains characters 'a'-'z', and the length will be not longer than 50.
The last line is the description, and the length will be not longer than 1000000.
Output
Print how many keywords are contained in the description.
Sample Input
1
5
she
he
say
shr
her
yasherhs
Sample Output
3
bestcode:
#include<iostream> #include<algorithm> #include<cstring> #include<cstdio> #include<queue> using namespace std; const int MAX = 550000; int kid[MAX][26],fail[MAX],v[MAX]; struct AcTrie { int rt,L; //初始化 void Init(){L=0;rt=newnode();} //新建节点 int newnode(){ v[L] = 0; memset(kid[L],-1,sizeof(kid[L])); return L++; } //建立trie树 void insert(char* s){ int now = rt; for(int i=0;s[i];++i){ int t = s[i]-'a'; if(kid[now][t]==-1) kid[now][t] = newnode(); now = kid[now][t]; } v[now]++; } //建立trie图 void Build() { queue<int> q; for(int i=0;i<26;++i){ if(kid[rt][i]==-1){ kid[rt][i] = rt; } else { fail[kid[rt][i]] = rt; q.push(kid[rt][i]); } } while(!q.empty()) { int now = q.front();q.pop(); for(int i=0;i<26;++i){ if(kid[now][i]==-1){ kid[now][i] = kid[fail[now]][i]; } else { fail[kid[now][i]] = kid[fail[now]][i]; q.push(kid[now][i]); } } } } //查询 int query(char* s) { int ans = 0; int now = rt,tmp; for(int i=0;s[i];++i){ int t = s[i]-'a'; now = tmp = kid[now][t]; while(tmp!=rt) { ans += v[tmp]; v[tmp] = 0; tmp = fail[tmp]; } } return ans; } }ac; char str[1000000+50]; int main() { #ifdef zsc freopen("input.txt","r",stdin); #endif int n,m,i,j,k; scanf("%d",&n); while(n--) { ac.Init(); scanf("%d",&m); while(m--) { scanf("%s",str); ac.insert(str); } ac.Build(); scanf("%s",str); printf("%d\n",ac.query(str)); } return 0; }
AC代码:
#include<iostream> #include<cstring> #include<string> #include<cstdio> #include<queue> using namespace std; const int MAX = 550000; struct trie { int root,L; int kid[MAX][26],fail[MAX],v[MAX]; trie() { L = 0; root =newnote(); } int newnote(); void build(); void insert(string str); int query(string str); }*ac; int trie::newnote() { v[L]=0; memset(kid[L],-1,sizeof(kid[L])); return L++; } void trie::build() { int i,now; queue<int> p; for(i=0;i<26;++i) { if(kid[root][i]==-1) { kid[root][i] = root; } else { fail[kid[root][i]] = root; p.push(kid[root][i]); } } while(!p.empty()) { now = p.front();p.pop(); for(i=0;i<26;++i) { if(kid[now][i]==-1) kid[now][i] = kid[fail[now]][i]; else { fail[kid[now][i]] = kid[fail[now]][i]; p.push(kid[now][i]); } } } } void trie::insert(string str) { int now = root; for(int i=0;str[i];++i) { int d = str[i] - 'a'; if(kid[now][d] == -1) { kid[now][d] = newnote(); } now = kid[now][d]; } v[now]++; } int trie::query(string str) { int tmp,now,res=0,i; now = root; for(i=0;str[i];++i) { tmp = now = kid[now][str[i]-'a']; while(root!=tmp) { res+=v[tmp]; v[tmp]=0; tmp = fail[tmp]; } } return res; } int main() { /*freopen("input.txt","r",stdin);*/ int n,m; string str; cin >> n; while(n--) { ac = new trie; cin >> m; while(m--) { cin >> str; ac->insert(str); } ac->build(); cin >> str; cout << ac->query(str) << endl; delete ac; } return 0; }
注释代码&&模板:
#include<iostream> #include<cstring> #include<string> #include<cstdio> #include<queue> using namespace std; const int MAX = 55; struct actrie { int root,L;//根节点,节点数 int kid[MAX][26],fail[MAX],v[MAX]; //孩子节点,失败返回,单串的最后位置数 int newnote();//初始化字典树 actrie() { L=0;root=newnote(); } void build();//建立fail数组 int query(string st);//查找函数 void insert(string str);//插入函数 }ac; int actrie::newnote() { v[L]=0; memset(kid[L],-1,sizeof(kid[L])); return L++; } void actrie::build() { queue<int> p; fail[root] = root; for(int i=0;i<26;++i) { if(kid[root][i]==-1)//不存在的 kid[root][i]=root; else { fail[kid[root][i]] = root;//储存失败后的节点 p.push(kid[root][i]); } } while(!p.empty()) { int now = p.front();p.pop(); for(int i=0;i<26;++i) { if(kid[now][i]==-1) kid[now][i] = kid[fail[now]][i]; else { fail[kid[now][i]] = kid[fail[now]][i]; p.push(kid[now][i]); } } } } void actrie::insert(string str) { int now = root; for(int i=0;str[i];++i) { int d = str[i] - 'a'; if(kid[now][d]==-1) { kid[now][d] = newnote(); } now = kid[now][d]; } v[now]++;//在字符串最后加1,证明存在这样的字符串 } int actrie::query(string st) { int res=0; int now = root,tmp; for(int i=0;st[i];++i) { tmp = now = kid[now][st[i]-'a']; while(tmp!=root) //每个节点都是不同的,相当于一棵树中的节点位置。当搜索完成了,就全部在根节点 { res+=v[tmp];//找到了匹配串,因为一开始已经规定了哪几个串,所以只有串尾有数值 v[tmp] = 0; tmp = fail[tmp]; } } return res; } int main() { int n,m,i; string str[10010],st; cin >> n; while(n--) { cin >> m; for(i=0;i<m;++i) { cin >> str[i]; ac.insert(str[i]); } ac.build(); cin >> st; cout << ac.query(st) << endl; } return 0; }
相关文章推荐
- 使用C++实现JNI接口需要注意的事项
- 关于指针的一些事情
- c++ primer 第五版 笔记前言
- share_ptr的几个注意点
- Lua中调用C++函数示例
- Lua教程(一):在C++中嵌入Lua脚本
- Lua教程(二):C++和Lua相互传递数据示例
- C++联合体转换成C#结构的实现方法
- C++编写简单的打靶游戏
- C++ 自定义控件的移植问题
- C++变位词问题分析
- C/C++数据对齐详细解析
- C++基于栈实现铁轨问题
- C++中引用的使用总结
- 使用Lua来扩展C++程序的方法
- C++中调用Lua函数实例
- Lua和C++的通信流程代码实例
- C与C++之间相互调用实例方法讲解
- C++ Custom Control控件向父窗体发送对应的消息
- C++中拷贝构造函数的应用详解