說一下這題要注意的地方,因為目標串裡面有不是大寫字母的字符,所以每次進行匹配的時候要判斷一下,如果不是大寫字母就continue掉,注意此時要把P指針指向根節點。
其他就沒什麼了,就是模版AC自動機。
對了,還有就是題目是多組輸入。。。。。。WA的少年趕緊去改掉。。目測就能過了。。
更新了刪除節點,釋放內存,因為做到一道題目不釋放內存會MLE,所以把這裡前面的代碼也加進去,方便以後整理模版。
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <string>
#include <cmath>
#include <cstring>
#include <queue>
#include <set>
#include <vector>
#include <stack>
#include <map>
#include <iomanip>
#define PI acos(-1.0)
#define Max 2505
#define inf 1<<28
#define LL(x) ( x << 1 )
#define RR(x) ( x << 1 | 1 )
#define REP(i,s,t) for( int i = ( s ) ; i <= ( t ) ; ++ i )
#define ll long long
#define mem(a,b) memset(a,b,sizeof(a))
#define mp(a,b) make_pair(a,b)
#define PII pair<int,int>
using namespace std;
struct node {
node *fail ;
node *next[26] ;
int count ;
int id ;
node() {
fail = 0 ;
count = 0 ;
mem(next , 0) ;
id = 0 ;
}
}*qe[5000005] ;
node *root = 0 ;
//insert a[] .
void insert(char *a ,int id) {
node *p = root ;
int l = strlen(a) ;
for (int i = 0 ; i < l ; i ++ ) {
int tt = a[i] - 'A' ;
if(p -> next[tt] == 0) {
p -> next[tt] = new node() ;
}
p = p -> next[tt] ;
}
p -> count ++ ;
p -> id = id ;
}
//build *fail .
void build() {
root -> fail = 0 ;
int h = 0 , t = 0 ;
qe[h ++ ] = root ;
while(h > t) {
node *temp = qe[t ++ ] ;
node *p = 0 ;
for (int i = 0 ; i < 26 ; i ++ ) {
if(temp -> next[i] != 0) {
if(temp == root)temp -> next[i] -> fail = root ;
else {
p = temp -> fail ;
while(p != 0) {
if(p -> next[i] != 0) {
temp -> next[i] -> fail = p -> next[i] ;//找到匹配
break ;
}
p = p -> fail ;
}
if(p == 0)temp -> next[i] -> fail = root ;//如果沒找到,則將fail指向root
}
qe[h ++ ] = temp -> next[i] ;
}
}
}
}
int anss[1111] ;
int search(char *a) {
int l = strlen(a) ;
node *p = root ;
int ans = 0 ;
for (int i = 0 ; i < l ; i ++ ) {
int tt = a[i] - 'A' ;
if(tt < 0 || tt >= 26){
p = root ;
continue ;
}
while(p -> next[tt] == 0 && p != root)p = p -> fail ;
p = p -> next[tt] ;
p = (p == 0) ? root : p ;
node *temp = p ;
while(temp != root && temp -> count != 0) {
ans += temp -> count ;
anss[temp -> id] ++ ;
//temp -> count = -1 ;
temp = temp -> fail ;
}
}
return ans ;
}
char a[1111][55] ;
char b[2000005] ;
void deleteAll(node *p){
for (int i = 0 ; i < 26 ;i ++ ){
if(p -> next[i] != 0){
deleteAll(p -> next[i]) ;
}
}
delete p ;
}
int main() {
int n ;
while(cin >> n ) {
mem(anss, 0) ;
root = new node() ;
for (int i = 1 ; i <= n ; i ++ ) {
scanf("%s",a[i]) ;
insert(a[i] , i) ;
}
build() ;
scanf("%s",b) ;
search(b) ;
for (int i = 1 ; i <= n ; i ++ ) {
if(anss[i]) {
cout << a[i] << ": " << anss[i] << endl;
}
}
deleteAll(root) ;
}
return 0 ;
}
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <string>
#include <cmath>
#include <cstring>
#include <queue>
#include <set>
#include <vector>
#include <stack>
#include <map>
#include <iomanip>
#define PI acos(-1.0)
#define Max 2505
#define inf 1<<28
#define LL(x) ( x << 1 )
#define RR(x) ( x << 1 | 1 )
#define REP(i,s,t) for( int i = ( s ) ; i <= ( t ) ; ++ i )
#define ll long long
#define mem(a,b) memset(a,b,sizeof(a))
#define mp(a,b) make_pair(a,b)
#define PII pair<int,int>
using namespace std;
struct node {
node *fail ;
node *next[26] ;
int count ;
int id ;
node() {
fail = 0 ;
count = 0 ;
mem(next , 0) ;
id = 0 ;
}
}*qe[5000005] ;
node *root = 0 ;
//insert a[] .
void insert(char *a ,int id) {
node *p = root ;
int l = strlen(a) ;
for (int i = 0 ; i < l ; i ++ ) {
int tt = a[i] - 'A' ;
if(p -> next[tt] == 0) {
p -> next[tt] = new node() ;
}
p = p -> next[tt] ;
}
p -> count ++ ;
p -> id = id ;
}
//build *fail .
void build() {
root -> fail = 0 ;
int h = 0 , t = 0 ;
qe[h ++ ] = root ;
while(h > t) {
node *temp = qe[t ++ ] ;
node *p = 0 ;
for (int i = 0 ; i < 26 ; i ++ ) {
if(temp -> next[i] != 0) {
if(temp == root)temp -> next[i] -> fail = root ;
else {
p = temp -> fail ;
while(p != 0) {
if(p -> next[i] != 0) {
temp -> next[i] -> fail = p -> next[i] ;//找到匹配
break ;
}
p = p -> fail ;
}
if(p == 0)temp -> next[i] -> fail = root ;//如果沒找到,則將fail指向root
}
qe[h ++ ] = temp -> next[i] ;
}
}
}
}
int anss[1111] ;
int search(char *a) {
int l = strlen(a) ;
node *p = root ;
int ans = 0 ;
for (int i = 0 ; i < l ; i ++ ) {
int tt = a[i] - 'A' ;
if(tt < 0 || tt >= 26){
p = root ;
continue ;
}
while(p -> next[tt] == 0 && p != root)p = p -> fail ;
p = p -> next[tt] ;
p = (p == 0) ? root : p ;
node *temp = p ;
while(temp != root && temp -> count != 0) {
ans += temp -> count ;
anss[temp -> id] ++ ;
//temp -> count = -1 ;
temp = temp -> fail ;
}
}
return ans ;
}
char a[1111][55] ;
char b[2000005] ;
void deleteAll(node *p){
for (int i = 0 ; i < 26 ;i ++ ){
if(p -> next[i] != 0){
deleteAll(p -> next[i]) ;
}
}
delete p ;
}
int main() {
int n ;
while(cin >> n ) {
mem(anss, 0) ;
root = new node() ;
for (int i = 1 ; i <= n ; i ++ ) {
scanf("%s",a[i]) ;
insert(a[i] , i) ;
}
build() ;
scanf("%s",b) ;
search(b) ;
for (int i = 1 ; i <= n ; i ++ ) {
if(anss[i]) {
cout << a[i] << ": " << anss[i] << endl;
}
}
deleteAll(root) ;
}
return 0 ;
}