[HDU - 2222] 키워드 검색 (AC 자동 템 플 릿)

3319 단어 데이터 구조
AC 자동 동기 템 플 릿 문 제 는 자신의 손 으로 템 플 릿 을 한 번 두 드 렸 다.
짝 짓 기 변 을 추가 할 때 각 노드 의 26 개의 알파벳 변 링크 의 하위 노드 를 한 번 훑 어 본다. 만약 에 결점 이 존재 한다 면 이 하위 노드 의 짝 짓 기 변 은 바로 주 결점 의 짝 짓 기 변 에 대응 하 는 노드 이다.
만약 에 결점 이 존재 하지 않 는 다 면 이 결점 은 주 결점 의 어 울 리 지 않 는 변 에 대응 하 는 결점 링크 의 하위 노드 에 직접 연 결 됩 니 다.
AC 자동 동기 가 너무 어려워...QAQ
11885512
2014-10-16 16:22:43
Accepted
2222
687MS
26688K
2772 B
G++
KinderRiven
#include
#include
#include
#include
#include
#include
#include
#include
using namespace std;
const int maxn = 555555;
const int maxn_sign = 26;
const int maxd = 1111111;
int root;
struct Trie{ //AC   
    int tr[maxn][maxn_sign];//Trie 
    int fail[maxn]; //   
    int val[maxn];
    int sz; //    
    int counts;
    int index(int c){
        if(c >= 'a' && c <= 'z')
            return c - 'a';
        if(c >= 'A' && c <= 'Z')
            return c - 'A';
    }
    void init(){   //     
        sz = 0; val[0] = 0; counts = 0;
        for(int i = 0; i < 26; i++) tr[0][i] = -1;
    }
    int newnode(){ //      
        val[sz] = 0;
        for(int i = 0; i < 26; i++) tr[sz][i] = -1;
        sz ++;
        return sz - 1;
    }
    void insert(char *str){
         int u = 0,n = strlen(str);
         for(int i = 0; i < n; i++){
            int e = index(str[i]);
            if(tr[u][e] == -1){  //      
                int d = newnode();
                tr[u][e] = d;
            }
            u = tr[u][e];
         }
         val[u] ++;
    }
    void buildfail(){
        queueq;
        fail[root] = root; //           
        for(int i = 0; i < 26; i++){
            if(tr[root][i] == -1)
               tr[root][i] = root;
            else{
                q.push(tr[root][i]);
                fail[tr[root][i]] = root;
            }
        }
        while(!q.empty()){
            int node = q.front(); q.pop();
            for(int i = 0; i < 26; i++){
                if(tr[node][i] == -1){
                   tr[node][i] = tr[fail[node]][i];
                }
                else{
                    fail[tr[node][i]] = tr[fail[node]][i];
                    q.push(tr[node][i]);
                }
            }
        }
    }
    void triecount(char *str){
         int L = strlen(str);
         int u = 0;
         for(int i = 0; i < L;i ++){
            u = tr[u][index(str[i])];
            int temp = u;
            while(temp != root){
                counts += val[temp];
                val[temp] = 0;
                temp = fail[temp];
            }
         }
    }
};
Trie ac;
char s[maxd];
int main(){
    int T;
    scanf("%d",&T);
    while(T--){
        ac.init();
        int n;
        root = ac.newnode();
        char str[55];
        scanf("%d",&n);
        for(int i = 0; i < n; i++){
            scanf("%s",str);
            ac.insert(str);
        }
        scanf("%s",s);
        ac.buildfail();
        ac.triecount(s);
        printf("%d
",ac.counts); //printf("%d
",ac.sz); } return 0; }

좋은 웹페이지 즐겨찾기