You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

86 lines
2.3 KiB

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

#include <cstdio>
#include <cstring>
#include <algorithm>
#include <iostream>
using namespace std;
const int N = 1000010;
char s[150 + 10][70 + 10]; //模式串,第一维是多少个,第二维是具体的字符
char T[N]; //文本串 长度最大10^6
int n; //模式串数量
int cnt[N]; //每个模式串出现的次数
int tr[N][26], idx; // Trie树
int id[N]; // 节点号-mapping->模式串
void insert(char *s, int x) {
int p = 0;
for (int i = 0; s[i]; i++) {
int t = s[i] - 'a';
if (!tr[p][t]) tr[p][t] = ++idx;
p = tr[p][t];
}
id[p] = x; //记录:节点号-mapping->模式串
}
//构建AC自动机
int q[N], ne[N];
void bfs() {
int hh = 0, tt = -1;
for (int i = 0; i < 26; i++)
if (tr[0][i]) q[++tt] = tr[0][i];
while (hh <= tt) {
int p = q[hh++];
for (int i = 0; i < 26; i++) {
int t = tr[p][i];
if (!t)
tr[p][i] = tr[ne[p]][i];
else {
ne[t] = tr[ne[p]][i];
q[++tt] = t;
}
}
}
}
//查询字符串s在AC自动机中出现的次数
void query(char *s) {
int p = 0;
for (int i = 0; s[i]; i++) {
p = tr[p][s[i] - 'a'];
for (int j = p; j; j = ne[j])
if (id[j]) cnt[id[j]]++; //如果有模式串标记,更新出现次数
}
}
int main() {
//加快读入
ios::sync_with_stdio(false), cin.tie(0);
while (cin >> n && n) {
//每次清空
memset(tr, 0, sizeof tr);
memset(cnt, 0, sizeof cnt);
memset(ne, 0, sizeof ne);
memset(id, 0, sizeof id);
idx = 0;
for (int i = 1; i <= n; i++) {
cin >> s[i];
insert(s[i], i);
}
bfs();
cin >> T;
query(T);
int Max = 0;
for (int i = 1; i <= n; i++) Max = max(cnt[i], Max); //最后统计答案
printf("%d\n", Max);
//最大值可能很多个模式串匹配到,需要在获取完最大值后,再次循环输出符合最大值条件的所有模式串
for (int i = 1; i <= n; i++)
if (cnt[i] == Max) printf("%s\n", s[i]);
}
return 0;
}