标签:names 操作 字符串 output 标记 aac i++ 空格 冒号
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 29963 Accepted Submission(s): 6877
#include <stdio.h> #include <algorithm> #include <iostream> #include <string.h> #include <queue> #include <vector> using namespace std; int id,flag,tt; vector<int>V; struct Trie { int Next[500010][130]; int fail[500010],end[500010]; int root,L;//L用来标记节点序号,以广度优先展开的字典树的序号 int newnode() //建立新节点 { for(int i = 0;i < 130;i++) Next[L][i] = -1; //将该节点的后继节点域初始化 end[L++] = 0; return L-1; //返回当前节点编号 } void init() //初始化操作 { L = 0; root = newnode(); } void insert(char buf[]) { int len = strlen(buf); int now = root; for(int i = 0;i < len;i++) { if(Next[now][buf[i]] == -1) //如果未建立当前的后继节点,建立新的节点 Next[now][buf[i]] = newnode(); now = Next[now][buf[i]]; } end[now]=id++; } void build() { queue<int>Q; //用广度优先的方式,将树层层展开 fail[root] = root; for(int i = 0;i < 130;i++) if(Next[root][i] == -1) Next[root][i] = root; else { fail[Next[root][i]] = root; Q.push(Next[root][i]); } while( !Q.empty() ) { int now = Q.front(); Q.pop(); for(int i = 0;i < 130;i++) if(Next[now][i] == -1) Next[now][i] = Next[fail[now]][i];//该段的最后一个节点匹配后,跳到拥有最大公共后缀的fail节点继续匹配 else { fail[Next[now][i]]=Next[fail[now]][i];//当前节点的fail节点等于它前驱节点的fail节点的后继节点 Q.push(Next[now][i]); } } } int query(char buf[]) { int len = strlen(buf); int now = root; int res = 0; for(int i = 0;i < len;i++) { now = Next[now][buf[i]]; int temp = now; while( temp != root ) { if(end[temp]){ res++; V.push_back(end[temp]); } temp = fail[temp];//每次找最大公共后缀对应的fail节点 } } return res; } void debug() { for(int i = 0;i < L;i++) { printf("id = %3d,fail = %3d,end = %3d,chi = [",i,fail[i],end[i]); for(int j = 0;j < 130;j++) printf("%2d",Next[i][j]); printf("]\n"); } } }; char buf[1000010]; Trie ac; int main() { int n,ans,t,res,sum; while(scanf("%d",&n)!=EOF) { id=1; ac.init(); for(int i=0;i<n;i++) { scanf("%s",buf); ac.insert(buf); } ac.build(); scanf("%d",&t); sum=0; for(int i=1;i<=t;i++) { res=0; V.clear(); flag=0; scanf("%s",buf); ans=ac.query(buf); if(ans>0) { sum++; printf("web %d:",i); sort(V.begin(),V.end()); for(int i=0;i<V.size();i++){ if((i>0&&V[i]!=V[i-1])||i==0){ printf(" %d",V[i]); } } printf("\n"); } } printf("total: %d\n",sum); } return 0; }
标签:names 操作 字符串 output 标记 aac i++ 空格 冒号
原文地址:http://www.cnblogs.com/a249189046/p/7533586.html