题目描述
有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 ; }