给定n个模式串和1个文本串,求有多少个模式串在文本串里出现过。
#include <bits/stdc++.h> const int maxn = 3*1e6+5, M = 1e6+7; using namespace std; int siz, cur[maxn]; bool flag[maxn]; struct ac{ struct Sta{ int son[26], fail; int cnt, rr; }sta[maxn]; void init(){ siz = 1; } void insert(char *S, int tot){ int len = strlen(S); int now = 0; for(int i = 0; i < len; i++){ char c = S[i]; if(sta[now].son[c-'a'] == 0) sta[now].son[c-'a'] = siz++; now = sta[now].son[c-'a']; } sta[now].cnt++; }; void build(){ queue <int> Q; Q.push(0); while(!Q.empty()){ int u = Q.front(); Q.pop(); for(int i = 0; i < 26; i++){ if(sta[u].son[i]){ if(u == 0)sta[sta[u].son[i]].fail = 0; else sta[sta[u].son[i]].fail = sta[sta[u].fail].son[i]; Q.push(sta[u].son[i]); } else sta[u].son[i] = sta[sta[u].fail].son[i]; } } } int match(char *S){ int now = 0, res = 0; int len = strlen(S); for(int i = 0; i < len; i++){ char c = S[i]; now = sta[now].son[c - 'a']; for(int t = now; t && !flag[t]; t = sta[t].fail) res += sta[t].cnt, flag[t] = 1; } return res; } int Query(int t){ return sta[cur[t]].rr; } }Tr; char a[maxn][55]; char s[M]; char S[M]; int main() { int n ,m; scanf("%d", &n); Tr.init(); for(int i = 1; i <= n; i++){ // scanf(" "); scanf("%s", s); Tr.insert(s, i); } Tr.build(); // scanf(" "); scanf("%s", S); printf("%d ", Tr.match(S)); return 0; }
有 NN 个由小写字母组成的模式串以及一个文本串 TT 。每个模式串可能会在文本串中出现多次。你需要找出哪些模式串在文本串 TT 中出现的次数最多。
#include <bits/stdc++.h> const int maxn = 3*1e6+5, M = 1e6+7; using namespace std; int siz; bool flag[maxn]; struct Result{ int sum , id; }ans[M]; struct ac{ struct Sta{ int son[26], fail; int end, rr; }sta[maxn]; void clear(int x){ memset(sta[x].son, 0, sizeof(sta[x].son)); sta[x].end = sta[x].fail = 0; } void insert(char *S, int tot){ int len = strlen(S); int now = 0; for(int i = 0; i < len; i++){ char c = S[i]; if(sta[now].son[c-'a'] == 0){ sta[now].son[c-'a'] = ++siz; clear(siz); } now = sta[now].son[c-'a']; } sta[now].end = tot; }; void build(){ queue <int> Q; Q.push(0); while(!Q.empty()){ int u = Q.front(); Q.pop(); for(int i = 0; i < 26; i++){ if(sta[u].son[i]){ if(u == 0)sta[sta[u].son[i]].fail = 0; else sta[sta[u].son[i]].fail = sta[sta[u].fail].son[i]; Q.push(sta[u].son[i]); } else sta[u].son[i] = sta[sta[u].fail].son[i]; } } } void match(char *S){ int now = 0, res = 0; int len = strlen(S); for(int i = 0; i < len; i++){ char c = S[i]; now = sta[now].son[c - 'a']; for(int t = now; t; t = sta[t].fail) ans[sta[t].end].sum++; } } }Tr; char a[M][75]; char S[M]; bool cmp(Result a, Result b){ return a.sum == b.sum ? a.id < b.id : a.sum > b.sum; } int main() { int n ,m; while(scanf("%d", &n) == 1){ if(!n)break; siz = 0; for(int i = 1; i <= n; i++){ ans[i].id = i; ans[i].sum = 0; } Tr.clear(0); for(int i = 1; i <= n; i++){ scanf("%s", a[i]); Tr.insert(a[i], i); } Tr.build(); scanf("%s", S); Tr.match(S); sort(ans+1, ans+1+n, cmp); printf("%d ", ans[1].sum); for(int i = 1; i <= n; i++){ if(ans[i].sum < ans[1].sum)break; printf("%s ", a[ans[i].id]); } } return 0; }