您的位置:首页 > 其它

AC自动机模板

2017-07-26 15:49 369 查看
#include<bits/stdc++.h>
using namespace std;

const int maxn = 1e7 + 5;
const int nsize = 26;

struct node
{
node *next[nsize];
node *fail;
int sum;
};

int cnt;
node *root;

//构造字典树
void Insert(char *s)
{
node *newnode,*p;
p = root;
for(int i = 0; s[i]; i++)
{
int x = s[i] - 'a';
if(p->next[x] == NULL)
{
newnode=(struct node *)malloc(sizeof(struct node));
for(int j=0; j<nsize; j++) newnode->next[j] = 0;
newnode->sum = 0;
newnode->fail = 0;
p->next[x]=newnode;
}
p = p->next[x];
}
p->sum++;
}

//构造失败指针
void build_fail() {
queue<node*> Q;
Q.push(root);
while (!Q.empty()) {
node *p = Q.front();
Q.pop();
for(int i = 0; i < nsize; i++) {
if (p->next[i]) {
if (p == root)
p->next[i]->fail = p;
else {
node *tmp = p->fail;
while (tmp) {
if (tmp->next[i]) {
p->next[i]->fail = tmp->next[i];
break;
}
else tmp = tmp->fail;
}
if (!tmp) p->next[i]->fail = root;
}
Q.push(p->next[i]);
}
}
}
return ;
}

//匹配
void ac_automation(char *ch)
{
node *p = root;
int len = strlen(ch);
for(int i = 0; i < len; i++)
{
int x = ch[i] - 'a';
while(!p->next[x] && p != root)
{
p = p->fail;
if(p->sum > 0)
{
cnt += p->sum;  //不想改变sun值就用vis数组标记
p->sum = -1;
}
}
p = p->next[x];
if(!p) p = root;
node *temp = p;
while(temp != root)
{
if(temp->sum > 0)
{
cnt += temp->sum;
temp->sum = -1;
}
else break;
temp = temp->fail;
}
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: