AC自动机 多字符串匹配 code

来源:互联网 发布:钱夫人 淘宝 编辑:程序博客网 时间:2024/05/16 16:56

AC自动机 有多个匹配串适用



#include <stdio.h>#include <stdlib.h>#include <string.h>#include <queue> using namespace std;   #define NUM (26) struct trienode {      trienode *fail;       // 失败指针    trienode *next[NUM];  // Trie每个节点含26个孩子    int count;            // 以该节点作为结尾的单词数量    trienode() {          // 构造函数        fail=NULL;         count=0;         memset(next, 0, sizeof(next));     } };  void TrieInsert(trienode *root , const char *str){char ch;    trienode *p = root;       while((ch = *str++)){         int index = ch - 'a';         if(p->next[index] == NULL) p->next[index]= new trienode();          p = p->next[index];    }     p->count++; return;}void TrieCreate(trienode **root){*root = new trienode();return;}void TrieDestroy(trienode *root){trienode *p = root;if (!p)return;for (int i = 0; i < NUM; i++) {if (p->next[i])TrieDestroy(p->next[i]); }delete p;return;}void BuildAc(trienode *root){queue<trienode *> qu;    root->fail=NULL;     qu.push(root);    while(!qu.empty()) {trienode *p=NULL;         trienode *temp = qu.front();qu.pop();                for(int i = 0; i < NUM; i++) {             if(temp->next[i] != NULL) {                 if(temp == root) temp->next[i]->fail = root;                                 else {                     p = temp->fail;while(p && p->next[i] == NULL)p = p->fail;temp->next[i]->fail = p ? p->next[i] : root;                 }                 qu.push(temp->next[i]);              }         }       }return;} // Ac自动机多模式串匹配, 返回匹配的个数int AcStrSearch(const char *str, trienode *root){char ch;int cnt = 0;     trienode *p = root;if (!str)return -1;    while ((ch = *str++)) {          int index = ch - 'a';trienode *temp;        while (p->next[index] == NULL && p != root)p = p->fail;         p = p->next[index];         p = p ? p : root;        temp = p;        while(temp != root && temp->count != -1) {             cnt += temp->count;             temp->count = -1;             temp = temp->fail;         }                      }        return cnt; } char pat[256];     // 输入的匹配串char txt[100000];  // 输入的正文主串int main(){     int n1, n2;    scanf("%d",&n1);     while(n1--){char *str;trienode *root;TrieCreate(&root);                 scanf("%d",&n2);         while(n2--){             scanf("%s", pat);             TrieInsert(root, pat);         }         BuildAc(root);        scanf("%s", txt);str = txt;        printf("%d\n", AcStrSearch(str, root));TrieDestroy(root);    }     return 0; }


0 0
原创粉丝点击