HDU 2222 (AC 자동 기 입문 문제)

6877 단어 ACM-데이터 구조
제목 링크: Keywords Search AC 자동 입력 스티커: 자동 알고리즘 상세 설명 (제 가 요 리 를 비교 할 수 있 습 니 다. 블 로 거 는 Insert () 와 build ac automation () 두 함수 에 대한 해석 을 잘 모 릅 니 다. 저 와 같은 상황 을 가 진 친구 가 코드 이해 알고리즘 을 선택 하 는 것 을 권장 합 니 다)
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#define mem(a,b) memset(a,b,sizeof(a))
#define INF 0x7fffffff
typedef long long ll;
using namespace std;

const int kind_num = 26;
struct node{
    node *fail;
    node *next[kind_num];
    int countt;
    node(){
        fail = NULL;
        countt = 0;
        memset(next,NULL,sizeof(next));
    }
}*q[500010];

char keyword[51];
char str[1000010];
int head,tail;

void Insert(char *str,node *root){
    node *p = root;
    int i = 0,kind;
    while(str[i]){
        kind = str[i] - 'a';
        if(p -> next[kind] == NULL){
            p -> next[kind] = new node();
        }
        p = p -> next[kind];
        i++;
    }
    p -> countt++;// ++,          
}

void build_ac_automation(node *root){
    int i;
    root -> fail = NULL;
    q[head++] = root;
    while(head != tail){
        node *tmp = q[tail++];
        node *p = NULL;
        for(int i = 0; i < 26; i++){
            if(tmp -> next[i] != NULL){
                if(tmp == root) tmp -> next[i] -> fail = root;
                else{
                    p = tmp -> fail;
                    while(p != NULL){
                        if(p -> next[i] != NULL){
                            tmp -> next[i] -> fail = p -> next[i];
                            break;
                        }
                        p = p -> fail;
                    }
                    if(p == NULL) tmp -> next[i] -> fail = root;
                }
                q[head++] = tmp -> next[i];
            }
        }
    }
}

int query(node *root){
    int i = 0,cnt = 0,kind;
    node *p = root;
    while(str[i] != '\0'){
        kind = str[i] - 'a';
        while(p ->next[kind] == NULL && p != root) p = p -> fail;
        p = p -> next[kind];
        p = (p == NULL)?root:p;
        node *tmp = p;
        while(tmp != root && tmp -> countt != -1){
            cnt += tmp -> countt;
            tmp -> countt = -1;
            tmp = tmp -> fail;
        }
        i++;
    }
    return cnt;
}

void dele(node *root){
    int i;
    for(int i = 0; i < kind_num; i++){
        if(root -> next[i] != NULL){
            dele(root -> next[i]);
        }
    }
    free(root);
}

int main(){
    int n,t;
    scanf("%d",&t);
    while(t--){
        head = tail = 0;
        node *root = new node();
        scanf("%d",&n);
        getchar();
        for(int i = 0; i < n; i++){
            gets(keyword);
            Insert(keyword,root);
        }
        build_ac_automation(root);
        scanf("%s",str);
        printf("%d
"
,query(root)); dele(root); } return 0; }

좋은 웹페이지 즐겨찾기