题目描述
有NNN个由小写字母组成的模式串以及一个文本串TTT。每个模式串可能会在文本串中出现多次。你需要找出哪些模式串在文本串TTT中出现的次数最多。
输入格式
输入含多组数据。
每组数据的第一行为一个正整数NNN,表示共有NNN个模式串,1≤N≤1501 \leq N \leq 1501≤N≤150。
接下去NNN行,每行一个长度小于等于707070的模式串。下一行是一个长度小于等于10610^6106的文本串TTT。
输入结束标志为N=0N=0N=0。
输出格式
对于每组数据,第一行输出模式串最多出现的次数,接下去若干行每行输出一个出现次数最多的模式串,按输入顺序排列。
输入输出样例
输入 #1
2 aba bab ababababac 6 beta alpha haha delta dede tata dedeltalphahahahototatalpha 0
输出 #1
4 aba 2 alpha haha这题跟上一题不太一样,这题需要求的每个模式串块出现在文本串中的次数(出现次数)输出最多次数和该模式串(可能有多个),而上一题是询问文本串中出现了几个模式串(出现即可)主要区别:在于color记上有点变动,因为还要输出模式串,再对每个模式串根据color进行insearch一下就ok
#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <iostream>
#include <algorithm>
#include <iostream>
#include<cstdio>
#include<string>
#include<cstring>
#include <stdio.h>
#include <queue>
#include <string.h>
#include <vector>
#define ME(x , y) memset(x , y , sizeof(x))
#define SF(n) scanf("%d" , &n)
#define rep(i , n) for(int i = 0 ; i < n ; i ++)
#define INF 0x3f3f3f3f
#define mod 1000000007
using namespace std;
typedef long long ll ;
const int N = 1000009 ;
int tree[N][27] , k , color[N];
char str[1000009];
char s[151][71];
char aa[151][71];
int cnt ;
int fail[N];
int max1 ;
int ans ;
void winsert(char *a)
{
int p = 0 ;
for(int i = 0 ; a[i] ; i++)
{
int c = a[i] - 'a';
if(!tree[p][c]) tree[p][c] = ++k ;
p = tree[p][c];
}
color[p] = 1 ;
}
void getfail()
{
queue<int>q;
int p = 0 ;
for(int i = 0 ; i < 26 ; i++)
{
if(tree[p][i])
{
fail[tree[p][i]] = 0 ;
q.push(tree[p][i]);
}
}
while(!q.empty())
{
int next = q.front();
q.pop();
for(int i = 0 ; i < 26 ; i++)
{
if(tree[next][i])
{
fail[tree[next][i]] = tree[fail[next]][i];
q.push(tree[next][i]);
}
else
{
tree[next][i] = tree[fail[next]][i];
}
}
}
}
void query()
{
int p = 0 ;
for(int i = 0 ; str[i] ; i++)
{
p = tree[p][str[i] - 'a'];
for(int j = p ; j ; j = fail[j])
{
if(color[j])
{
color[j]++;
if(color[j] - 1 > max1)//注意要减一,因为本身为1.
max1 = color[j] - 1;
}
}
}
}
void winsearch(char *a)
{
int p = 0 ;
for(int i = 0 ; a[i] ; i++)
{
int c = a[i] - 'a';
if(!tree[p][c]) return ;
p = tree[p][c];
}
if(color[p] - 1 >= max1)
{
strcpy(aa[cnt++] , a);
}
}
int main()
{
int n ;
while(~scanf("%d" , &n) && n)
{
memset(tree , 0 , sizeof(tree));
memset(color , 0 , sizeof(color));
max1 = 0 ;
cnt = 0 ;
k = 0 ;
for(int i = 0 ; i < n ; i++)
{
scanf("%s" , s[i]);
winsert(s[i]);
}
getfail();
scanf("%s" , str);
query();
for(int i = 0 ; i < n ; i++)
{
winsearch(s[i]);
}
printf("%d\n" , max1);
for(int i = 0 ; i < cnt ; i++)
{
printf("%s\n" , aa[i]);
}
}
return 0 ;
}