中文题题意不再赘述
注意字符范围是可见字符,从32开始到95
char c - 32
#include <stdio.h> #include <string.h> #include <queue> #include <algorithm> using namespace std; inline int Max(int a,int b){return a>b?a:b;} inline int Min(int a,int b){return a>b?b:a;} #define N 10000 #define maxnode 57000 #define sigma_size 95 int pre[3]; struct Trie{ int ch[maxnode][sigma_size]; int val[maxnode]; int f[maxnode]; int sz; void init(){ sz=1; memset(ch[0],0,sizeof(ch[0])); val[0] = 0; } int idx(char c){ return c-32; } void Creat(char *s, int num){ int u = 0, len = strlen(s); for(int i = 0; i < len; i++){ int c = idx(s[i]); if(!ch[u][c]){ memset(ch[sz],0,sizeof(ch[sz])); val[sz]=0; ch[u][c] = sz++; } u = ch[u][c]; } val[u] = num ; //u若是单词结尾则为 +1 } int find(char *T, int num){ int len = strlen(T); int j = 0; int fir = 0; f[0] = 0; for(int i = 0; i < len; i++){ int c = idx(T[i]); j = ch[j][c]; if(!j) j = ch[0][c]; int temp = j; while(temp && val[temp]){ if(!fir) printf("web %d:", num); pre[fir++] = val[j]; if(fir == 3)break; temp = f[temp]; } } if(fir){ sort(pre, pre+fir); for(int k = 0; k < fir; k++)printf(" %d",pre[k]); printf(" "); } return fir>0; } void getFail(){ queue<int> q; f[0] = 0; //初始化队列 for(int c = 0; c < sigma_size; c++) if(ch[0][c])q.push(ch[0][c]); while(!q.empty()){ int r = q.front(); q.pop(); for(int c = 0; c < sigma_size; c++){ int u = ch[r][c]; if(!u){ ch[r][c] = ch[f[r]][c]; continue; } q.push(u); int v = f[r]; while(v && !ch[v][c]) v = f[v]; //沿失配边追溯到可以匹配的(非原点)位置 f[u] = ch[v][c]; } } } }; Trie ac; char S1[N],S2[N]; void InputString(){ gets(S1); } int main(){ int n; while(~scanf("%d",&n)){ ac.init(); getchar(); for(int i = 1; i <= n; i++){ InputString(); ac.Creat(S1, i); } ac.getFail(); int ANS = 0; scanf("%d",&n); getchar(); for(int i = 1; i <= n; i++){ InputString(); ANS += ac.find(S1, i); } printf("total: %d ",ANS); } return 0; } /* 3 a aa bbb ccc 2 a aabbbccc bbaacc ans: web 1: 1 2 3 total: 1 */