您的位置:首页 > 其它

AC自动机 多字符串匹配 code

2013-12-12 00:37 387 查看
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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  AC自动机