AC自动机

来源:互联网 发布:excel怎么将数据分列 编辑:程序博客网 时间:2024/06/08 15:11

知识点详解

hdu 2222


#include <iostream>#include <algorithm>#include <cstdio>#include <cstring>#include <string>using namespace std;const int N = 1e6+10;struct node{    int count;              //是否为该单词的最后一个节点    node *next[26];         //Tire每个节点的26个子节点(最多26个字母)    node *fail;             //失败指针    node() {                //构造函数初始化    fail = NULL;    count = 0;    memset(next, NULL, sizeof(next));    }}*q[500001];                //队列,方便用于bfs构造失败指针char keyword[55];           //输入的单词char str[N];                //模式串int head, tail;             //队列的头尾指针void insert(char *str, node *root) {int i = 0;node *p = root;while(str[i]) {int index = str[i] - 'a';if(p -> next[index] == NULL) p->next[index] = new node;p = p->next[index];i++;}p->count++;}void build_ac_automation(node *root) {root -> fail = NULL;q[head++] = root;while(head != tail) {node *temp = q[tail++];node *p = NULL;for(int i = 0; i < 26; i++) {if(temp->next[i] == NULL) continue;if(temp == root) temp->next[i]->fail = root;else {p = temp->fail;while(p!=NULL) {if(p->next[i] != NULL) {temp->next[i]->fail = p->next[i];break;}p = p->fail;} if(p == NULL) temp->next[i]->fail = root;}q[head++] = temp->next[i];}}}int query(char *str, node *root) {int i = 0;int cnt = 0;node *p = root;while(str[i]) {int index = str[i] - 'a';while(p->next[index]==NULL && p!=root) p = p->fail;p = p->next[index];p = (p==NULL)?root:p;node *temp = p;while(temp!=root && temp->count!=-1) {cnt += temp->count;temp->count = -1;temp = temp->fail;}i++;}return cnt;}int main() {int T;scanf("%d", &T);while(T--) {node *root = new node();head = tail = 0;int n;scanf("%d", &n);for(int i = 1; i <= n; i++) {scanf("%s", keyword);insert(keyword, root);}build_ac_automation(root);scanf("%s", str);printf("%d\n", query(str, root));}return 0;}  /*15shehesayshrheryasherhs*/




0 0
原创粉丝点击