题意:给n个模式串,m个待匹配串,每个串中包含哪些模式串打印出来。
思路:主要没有看清不止小写字母导致一直wa。用一个数组记录最后结尾的状态,然后去判断一下就好了。
#include <bits/stdc++.h> using namespace std; const int N = 1e5 + 6; int n; char a[510][210]; namespace AC { int tr[N][130], tot; int e[N], fail[N]; int v[N]; void insert(char *s,int w) { int u = 0; for (int i = 1; s[i]; i++) { if (!tr[u][s[i]]) tr[u][s[i]] = ++tot; u = tr[u][s[i]]; } e[u]++; v[w]=u; } queue<int> q; void build() { for (int i = 0; i < 130; i++) if (tr[0][i]) q.push(tr[0][i]); while (q.size()) { int u = q.front(); q.pop(); for (int i = 0; i < 130; i++) { if (tr[u][i]) fail[tr[u][i]] = tr[fail[u]][i], q.push(tr[u][i]); else tr[u][i] = tr[fail[u]][i]; } } } int query(char *t,int w) { int u = 0, res = 0; int k=0; set<int > ss; for (int i = 1; t[i]; i++) { u = tr[u][t[i]]; // 转移 for (int j = u; j && e[j] != 0; j = fail[j]) { if(e[j]>=1) { ss.insert(j); } } } if(ss.empty()) { return 0; } else { printf("web %d:",w); for(int i=1;i<=n;i++) { if(ss.count(v[i])) { printf(" %d",i); } } printf(" "); } } void init(){ memset(tr,0,sizeof(tr)); tot=0; memset(fail,0,sizeof(fail)); memset(e,0,sizeof(e)); } } // namespace AC char s[N]; int main() { int ans=0; scanf("%d", &n); for (int i = 1; i <= n; i++) scanf("%s", a[i] + 1), AC::insert(a[i],i); int t; AC::build(); scanf("%d",&t); for(int i=1;i<=t;i++){ scanf("%s", s + 1); if(AC::query(s,i)) { ans++; } } printf("total: %d ",ans); return 0; }