KMP代码
#include <cstdio>
#include <iostream>
#include <cstring>
using namespace std;
const int N= 1000010 ;
char a[ N] , b[ N] ;
int nex[ N] , la, lb, j;
int main ( ) {
cin>> a+ 1 >> b+ 1 ;
la= strlen ( a+ 1 ) ;
lb= strlen ( b+ 1 ) ;
for ( int i= 2 ; i<= lb; i++ ) {
while ( b[ j+ 1 ] != b[ i] && j) j= nex[ j] ;
if ( b[ j+ 1 ] == b[ i] ) j++ ;
nex[ i] = j;
}
j= 0 ;
for ( int i= 1 ; i<= la; i++ ) {
while ( j&& b[ j+ 1 ] != a[ i] ) {
j= nex[ j] ;
}
if ( b[ j+ 1 ] == a[ i] ) j++ ;
if ( j== lb) { printf ( "%d\n" , i- lb+ 1 ) ; j= nex[ j] ; }
}
for ( int i= 1 ; i<= lb; i++ ) printf ( "%d " , nex[ i] ) ;
return 0 ;
}
【模板】AC自动机(简单版)
#include <cstdio>
#include <string>
#include <queue>
using namespace std;
const int N= 1e6 + 10 ;
const int root= 0 ;
string str_in;
int n, cnt;
int ch[ N] [ 30 ] ;
int fail[ N] ;
int end[ N] ;
inline bool read_int ( int & now) {
char ch= getchar ( ) ;
bool fu= false ;
while ( ( ch== ' ' || ch== '\n' || ch== '\r' ) && ch!= EOF ) ch= getchar ( ) ;
if ( ch== '-' ) { fu= true ; ch= getchar ( ) ; }
while ( ch!= EOF && ch!= ' ' && ch!= '\n' && ch!= '\r' ) {
now= now* 10 + ( ch- '0' ) ;
ch= getchar ( ) ;
}
now* = ( ( fu) ? - 1 : 1 ) ;
}
inline void read_string ( ) {
str_in= "" ;
char ch= getchar ( ) ;
while ( ch!= EOF && ( ch== '\n' || ch== ' ' || ch== '\r' ) ) ch= getchar ( ) ;
while ( ch!= EOF && ch!= '\n' && ch!= ' ' && ch!= '\r' ) { str_in+ = ch; ch= getchar ( ) ; }
}
inline void Build ( string s) {
int ls= s. size ( ) ;
int now= root;
for ( int i= 0 ; i< ls; i++ ) {
if ( ! ch[ now] [ s[ i] - 'a' ] ) ch[ now] [ s[ i] - 'a' ] = ++ cnt;
now= ch[ now] [ s[ i] - 'a' ] ;
}
end[ now] ++ ;
}
inline void get_fail ( ) {
queue< int > q;
for ( int i= 0 ; i< 26 ; i++ ) {
if ( ch[ root] [ i] ) {
fail[ ch[ root] [ i] ] = root;
q. push ( ch[ root] [ i] ) ;
}
}
while ( ! q. empty ( ) ) {
int f= q. front ( ) ;
q. pop ( ) ;
for ( int i= 0 ; i< 26 ; i++ ) {
if ( ch[ f] [ i] ) {
fail[ ch[ f] [ i] ] = ch[ fail[ f] ] [ i] ;
q. push ( ch[ f] [ i] ) ;
} else {
ch[ f] [ i] = ch[ fail[ f] ] [ i] ;
}
}
}
}
int query ( string s) {
int sz= s. size ( ) ;
int x= root, ans= 0 ;
for ( int i= 0 ; i< sz; i++ ) {
x= ch[ x] [ s[ i] - 'a' ] ;
for ( int k= x; k&& end[ k] != - 1 ; k= fail[ k] ) {
ans+ = end[ k] ;
end[ k] = - 1 ;
}
}
return ans;
}
int main ( ) {
read_int ( n) ;
for ( int i= 1 ; i<= n; i++ ) {
read_string ( ) ;
Build ( str_in) ;
}
fail[ root] = 0 ;
get_fail ( ) ;
read_string ( ) ;
printf ( "%d" , query ( str_in) ) ;
return 0 ;
}
【模板】AC自动机(加强版)
#include <cstring>
#include <cstdio>
#include <string>
#include <queue>
using namespace std;
const int N= 500010 ;
const int root= 0 ;
int n, cnt;
int ch[ N] [ 30 ] ;
int fail[ N] ;
int ans[ N] ;
int val[ N] ;
string s[ 200 ] ;
inline void read_int ( int & now) {
now= 0 ;
char ch= getchar ( ) ;
bool fu= false ;
while ( ( ch== ' ' || ch== '\n' || ch== '\r' ) && ch!= EOF ) ch= getchar ( ) ;
if ( ch== '-' ) { fu= true ; ch= getchar ( ) ; }
while ( ch!= EOF && ch!= ' ' && ch!= '\n' && ch!= '\r' ) {
now= now* 10 + ( ch- '0' ) ;
ch= getchar ( ) ;
}
now* = ( ( fu) ? - 1 : 1 ) ;
}
inline void read_string ( string & str_in) {
str_in. clear ( ) ;
char ch= getchar ( ) ;
while ( ch!= EOF && ( ch== '\n' || ch== ' ' || ch== '\r' ) ) ch= getchar ( ) ;
while ( ch!= EOF && ch!= '\n' && ch!= ' ' && ch!= '\r' ) { str_in+ = ch; ch= getchar ( ) ; }
}
inline void Build ( string s, int vall) {
int ls= s. size ( ) ;
int now= root;
for ( int i= 0 ; i< ls; i++ ) {
if ( ! ch[ now] [ s[ i] - 'a' ] ) ch[ now] [ s[ i] - 'a' ] = ++ cnt;
now= ch[ now] [ s[ i] - 'a' ] ;
}
val[ now] = vall;
}
inline void get_fail ( ) {
queue< int > q;
for ( int i= 0 ; i< 26 ; i++ ) {
if ( ch[ root] [ i] ) {
fail[ ch[ root] [ i] ] = root;
q. push ( ch[ root] [ i] ) ;
}
}
while ( ! q. empty ( ) ) {
int f= q. front ( ) ;
q. pop ( ) ;
for ( int i= 0 ; i< 26 ; i++ ) {
if ( ch[ f] [ i] ) {
fail[ ch[ f] [ i] ] = ch[ fail[ f] ] [ i] ;
q. push ( ch[ f] [ i] ) ;
} else {
ch[ f] [ i] = ch[ fail[ f] ] [ i] ;
}
}
}
}
void query ( string s) {
int sz= s. size ( ) ;
int x= root;
for ( int i= 0 ; i< sz; i++ ) {
x= ch[ x] [ s[ i] - 'a' ] ;
for ( int k= x; k; k= fail[ k] ) { ans[ val[ k] ] ++ ; }
}
}
int main ( ) {
while ( 1 ) {
read_int ( n) ;
if ( ! n) {
return 0 ;
}
memset ( fail, 0 , sizeof ( fail) ) ;
memset ( ans, 0 , sizeof ( ans) ) ;
memset ( val, 0 , sizeof ( val) ) ;
memset ( ch, 0 , sizeof ( ch) ) ;
for ( int i= 1 ; i<= n; i++ ) {
read_string ( s[ i] ) ;
Build ( s[ i] , i) ;
}
fail[ root] = 0 ;
get_fail ( ) ;
read_string ( s[ 0 ] ) ;
query ( s[ 0 ] ) ;
int z_ans= 0 ;
for ( int i= 1 ; i<= n; i++ ) if ( z_ans< ans[ i] ) z_ans= ans[ i] ;
printf ( "%d\n" , z_ans) ;
bool fir= true ;
for ( int hao= 1 ; hao<= n; hao++ ) {
if ( ans[ hao] == z_ans) {
if ( ! fir) {
putchar ( '\n' ) ;
} else {
fir= false ;
}
int la= s[ hao] . size ( ) ;
for ( int i= 0 ; i< la; i++ ) {
printf ( "%c" , s[ hao] [ i] ) ;
}
}
}
putchar ( '\n' ) ;
}
}