思路:题目中有若干个模式川和一个主串,问在主串中出现了几种模式串。显然就是模式串构成AC_Tree(),然后再去匹配主串。
因为new 了空间的,所以最后要delete释放。
// #pragma comment(linker, "/STACK:1024000000,1024000000") #include <iostream> #include <algorithm> #include <iomanip> #include <sstream> #include <string> #include <stack> #include <queue> #include <deque> #include <vector> #include <map> #include <set> #include <stdio.h> #include <string.h> #include <math.h> #include <stdlib.h> #include <limits.h> using namespace std; typedef long long LL; typedef unsigned long long ULL; typedef pair<int,int> ii; const int inf = 1 << 30; const int INF = 0x3f3f3f3f; const int MOD = 1e9 + 7; struct node{ int cnt; struct node* fail; struct node* nxt[26]; node(){ fail = NULL; for (int i=0;i<26;i++) nxt[i]=NULL; cnt = 0;/*中间节点*/ } }; struct node* root; char keyword[55],str[1000005]; /*构建字典树*/ void build(char *str){ struct node *p=p=root; int index; for (;*str !='\0';str++){ index = *str - 'a'; if (p->nxt[index] == NULL) p->nxt[index] = new node(); p = p->nxt[index]; } p->cnt++; } /*构建失败指针*/ void AC_tree(){ queue<node*> que; root->fail = NULL; struct node *p,*tmp;/*i,j*/ que.push(root); while(!que.empty()){ p = que.front();//i que.pop(); for (int i=0;i<26;i++){ if (p->nxt[i] != NULL){ tmp = p->fail;//j while(tmp != NULL){ if (tmp->nxt[i] != NULL){ p->nxt[i]->fail = tmp->nxt[i]; break; } tmp = tmp->fail; } if (tmp == NULL) p->nxt[i]->fail = root; que.push(p->nxt[i]); } } } } int find(char *str){ int index; int sum = 0; struct node *p,*tmp; p = root; for (;*str!='\0';str++){ index = *str - 'a'; while(p->nxt[index] == NULL && p != root) p=p->fail; p = p->nxt[index]; if (p == NULL) p = root; tmp = p; while(tmp != root && tmp->cnt != -1){ sum += tmp->cnt; tmp->cnt = -1; tmp = tmp->fail; } } return sum; } void del(struct node* root){ for (int i=0;i<26;i++){ if (root->nxt[i] != NULL) del(root->nxt[i]); } delete root; } int main() { // freopen("in.txt","r",stdin); // freopen("out.txt","w",stdout); int T, n; while(scanf("%d",&T) != EOF){ while(T--){ root = new node(); scanf("%d",&n); getchar(); while(n--){ scanf("%s",keyword); build(keyword); } AC_tree(); scanf("%s",str); printf("%d\n",find(str)); del(root); } } return 0; }