题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=2896
题目大意:多个模式串。多个匹配串。其中串的字符范围是(0~127)。问匹配串中含有哪几个模式串。
解题思路:
AC自动机模板题。注意一下字符范围。
cnt记录这个模式串的个数改为这个模式串的index。
find的时候,把找到的index压入vector里面即可。
注意有多个匹配串,每次find之后会把last->cnt修改,原因是防止一个模式串出现了多次被压入vector,所以先备份一下,再还原回来。
#include "cstdio" #include "cstring" #include "string" #include "iostream" #include "queue" #include "vector" #include "algorithm" using namespace std; #define maxn 130 struct Trie { Trie *next[maxn],*fail; int cnt; }*root; struct status { Trie *last; int cnt; status(Trie *last,int cnt):last(last),cnt(cnt) {} }; Trie *newnode() { Trie *ret=new Trie; memset(ret->next,0,sizeof(ret->next)); ret->fail=0; ret->cnt=0; return ret; } void init() {root=newnode();} void Insert(string str,int index) { Trie *pos=root; for(int i=0;i<str.size();i++) { int c=str[i]; if(!pos->next[c]) pos->next[c]=newnode(); pos=pos->next[c]; } pos->cnt=index; } void getfail() { queue<Trie *> Q; for(int c=0;c<maxn;c++) { if(root->next[c]) { root->next[c]->fail=root; Q.push(root->next[c]); } else root->next[c]=root; } while(!Q.empty()) { Trie *x=Q.front();Q.pop(); for(int c=0;c<maxn;c++) { if(x->next[c]) { x->next[c]->fail=x->fail->next[c]; Q.push(x->next[c]); } else x->next[c]=x->fail->next[c]; } } } vector<int> find(string str) { Trie *pos=root,*last; queue<status> Q; vector<int> ans; for(int i=0;i<str.size();i++) { int c=str[i];last; if(pos->next[c]) { pos=pos->next[c]; last=pos; while(last->cnt) { Q.push(status(last,last->cnt)); ans.push_back(last->cnt); last->cnt=0; //修改last->cnt last=last->fail; } } } while(!Q.empty()) //恢复last->cnt { status x=Q.front();Q.pop(); x.last->cnt=x.cnt; } return ans; } int main() { //freopen("in.txt","r",stdin); ios::sync_with_stdio(false); int n,m; string tt; while(cin>>n) { init(); for(int i=1;i<=n;i++) { cin>>tt; Insert(tt,i); } getfail(); cin>>m; int cnt=0; for(int i=1;i<=m;i++) { cin>>tt; vector<int> ans=find(tt); sort(ans.begin(),ans.end()); if(!ans.size()) continue; cnt++; printf("web %d:",i); for(int j=0;j<ans.size();j++) printf(" %d",ans[j]); printf("\n"); } printf("total: %d\n",cnt); } }
2871595 | neopenx | HDU | 2896 | Accepted | 29988 | 343 | C++ | 2565 |
9 min ago |
时间: 2024-10-19 00:27:52