当前位置: 首页 > 工具软件 > AutoMan > 使用案例 >

贴瓷砖(AC_AUTOMAN)

阎晔
2023-12-01

A string S of N chars is given
We were asked to use m strings to match . Each string can be used serval times .strings for matching can intersect with each other .
The question is to find out how many chars of S can’t be matched .

The solution is AC_AUTOMAN .
this is the first time I type this algorithm .

#include<cstdio>
#include<cstring>
#include<algorithm>

using namespace std ;

#define N 300010
#define M 5100

char s[N] , z[M] ;

int i , j , k , n , m , T ;

int q[4000010] ;

struct AC_Automan {
    AC_Automan() {
        Len = -1 ;
    }
    int s[27] , nx , Len , de ;
    bool En ;
}g[4000010] ;

int tag[N] ;

int main() { 
    scanf("%d%s%d",&n,s,&m ) ;
    for( i=1 ; i<=m ; i++ ) {
        scanf("%s",z ) ;
        int l = strlen( z ) ;
        int x = 0 ;
        for( j=0 ; j<l ; j++ ) {
            if( g[x].s[ z[j]-'a' ]==0 ) 
                g[x].s[ z[j]-'a' ] = ++ T ;
            x = g[x].s[ z[j]-'a' ] ;
        }
        g[x].En = 1 ;
    }
    int l = 0 , r = 0 ;
    for( i=0 ; i<26 ; i++ ) if( g[0].s[i] ) q[++r] = g[0].s[i] ;
    while( l!=r ) {
        int x = q[++l] ;
        for( i=0 ; i<26 ; i++ ) if( g[x].s[i] ) {
            int tmp = q[++r] = g[x].s[i] ;
            g[tmp].nx = g[ g[x].nx ].s[i] ;
            g[tmp].de = g[x].de + 1 ;
        } else g[x].s[i] = g[ g[x].nx ].s[i] ;
        if( g[x].En ) g[x].Len = g[x].de  ;
        if( g[x].Len<0 ) g[x].Len = g[ g[x].nx ].Len ;
    }   
    int x = 0 ;
    for( i=0 ; i<n ; i++ ) {
        x = g[x].s[ s[i]-'a' ] ;
        if( g[x].Len>=0 ) tag[ i-g[x].Len ] ++ , tag[i+1] -- ;
    }
    int ans = 0 , cover = 0 ;
    for( i=0 ; i<n ; i++ ) cover += tag[i] , ans += ( cover == 0 ) ;
    printf("%d\n",ans ) ;
}

Here are some tips :
the void root ‘d better be zero for convenience .
the fail pointer tips ::
“`
for( i=0 ; i<26 ; i++ ) if( g[x].s[i] ) {
int tmp = q[++r] = g[x].s[i] ;
g[tmp].nx = g[ g[x].nx ].s[i] ;
g[tmp].de = g[x].de + 1 ;
} else g[x].s[i] = g[ g[x].nx ].s[i] ;
if( g[x].En ) g[x].Len = g[x].de ;
if( g[x].Len<0 ) g[x].Len = g[ g[x].nx ].Len ;

“`
this is the whole procedure of bfs , I think this is the main part of AC_AM .
That told the construction of failure pointer .

 类似资料: