版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/Tc_To_Top/article/details/84702336
题目描述
有N个由小写字母组成的模式串以及一个文本串T。每个模式串可能会在文本串中出现多次。你需要找出哪些模式串在文本串T中出现的次数最多。
输入输出格式
输入格式:
输入含多组数据。
每组数据的第一行为一个正整数N,表示共有N个模式串,1≤N≤150。
接下去N行,每行一个长度小于等于70的模式串。下一行是一个长度小于等于10^6的文本串T。
输入结束标志为N=0。
输出格式:
对于每组数据,第一行输出模式串最多出现的次数,接下去若干行每行输出一个出现次数最多的模式串,按输入顺序排列。
输入输出样例
输入样例#1:
2 aba bab ababababac 6 beta alpha haha delta dede tata dedeltalphahahahototatalpha 0
输出样例#1:
4 aba 2 alpha haha
题目链接:https://www.luogu.org/problemnew/show/P3796
题目分析:常规操作
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <queue>
#include <map>
#include <string>
#include <iostream>
using namespace std;
int const MAX = 1e6 + 5;
char s[MAX];
struct AC {
int nxt[MAX][26], tot, root, fail[MAX];
int end[MAX];
pair<int, string> str[MAX];
queue<int> q;
int NewNode() {
fail[tot] = 0;
end[tot] = 0;
str[tot].second = "";
memset(nxt[tot], -1, sizeof(nxt[tot]));
return tot++;
}
void Init() {
tot = 0;
root = NewNode();
}
void Insert(int id, char *s) {
int p = root, len = strlen(s);
for (int i = 0; i < len; i++) {
int idx = s[i] - 'a';
if (nxt[p][idx] == -1) {
nxt[p][idx] = NewNode();
}
p = nxt[p][idx];
}
end[p]++;
str[p] = make_pair(id, s);
}
void Build() {
fail[root] = root;
q.push(root);
while (!q.empty()) {
int p = q.front();
q.pop();
for (int i = 0; i < 26; i++) {
if (nxt[p][i] == -1) {
nxt[p][i] = (p == root) ? root : nxt[fail[p]][i];
} else {
fail[nxt[p][i]] = (p == root) ? root : nxt[fail[p]][i];
q.push(nxt[p][i]);
}
}
}
}
void Query(char *s) {
map< pair<int, string>, int> mp;
map< pair<int, string>, int> :: iterator it;
int len = strlen(s), cur = root;
for (int i = 0; i < len; i++) {
int idx = s[i] - 'a';
while (nxt[cur][idx] == -1 && cur != root) {
cur = fail[cur];
}
cur = nxt[cur][idx];
int p = cur;
while (p != root) {
if (end[p]) {
mp[str[p]]++;
}
p = fail[p];
}
}
int ma = 0;
for (it = mp.begin(); it != mp.end(); it++) {
ma = max(ma, it -> second);
}
printf("%d\n", ma);
for (it = mp.begin(); it != mp.end(); it++) {
if (it -> second == ma) {
cout << (it -> first).second << endl;
}
}
}
}ac;
int main() {
int n;
while (scanf("%d", &n) && n) {
ac.Init();
for (int i = 0; i < n; i++) {
scanf("%s", s);
ac.Insert(i, s);
}
ac.Build();
scanf("%s", s);
ac.Query(s);
}
}