解题思路:
跟上一题类似,仍然是AC自动机的简单应用,记录一下每个串出现的次数即可。、
#include <iostream> #include <cstring> #include <cstdlib> #include <cstdio> #include <cmath> #include <cstring> #include <vector> #include <queue> #include <string.h> #include <stack> #include <algorithm> using namespace std; char str[1010][60]; struct Trie { int next[1010*50][128],fail[1010*50],end[1010*50]; int root,L; int newnode() { for(int i = 0;i < 128;i++) next[L][i] = -1; end[L++] = -1; return L-1; } void init() { L = 0; root = newnode(); } void insert(char buf[], int id) { 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 < 128;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 < 128;i++) if(next[now][i] == -1) next[now][i] = next[fail[now]][i]; else { fail[next[now][i]]=next[fail[now]][i]; Q.push(next[now][i]); } } } int num[1010]; int query(char buf[],int n) { int len = strlen(buf); int now = root; for(int i=1;i<=n;i++) num[i] = 0; for(int i = 0;i < len;i++) { now = next[now][buf[i]]; int temp = now; while( temp != root ) { if(end[temp] != -1) { num[end[temp]]++; } temp = fail[temp]; } } for(int i=1;i<=n;i++) if(num[i] > 0) printf("%s: %d\n", str[i], num[i]); } }; char buf[2000010]; Trie ac; int main() { int n, m; while(scanf("%d", &n)!=EOF) { ac.init(); for(int i=1;i<=n;i++) { scanf("%s", str[i]); ac.insert(str[i], i); } ac.build(); scanf("%s", &buf); ac.query(buf, n); } return 0; }
版权声明:本文为博主原创文章,未经博主允许不得转载。
时间: 2024-09-29 15:33:39