您的位置:首页 > 其它

AC自动机 模板

2017-09-26 23:16 309 查看
#include<iostream>
#include<stdio.h>
#include<string.h>
#include<string>
#include<algorithm>
#include<queue>
using namespace std;
const int maxnode = 500000+5;
struct trie
{
int sz, root, val[maxnode], next[maxnode][30], fail[maxnode];
int cnt = 0;
queue<int>q;
void init()
{
sz = root = 0;
val[0] = 0;
memset(next, -1, sizeof(next));
}
void insert(string s)
{
int i, j, u = 0, len = s.size();
for (i = 0; i < len; i++)
{
int c = s[i] - 'a';
if (next[u][c] == -1)
{
sz++;
val[sz] = 0;
next[u][c] = sz;
}
u = next[u][c];
}
val[u]++;
}
void build()
{
while (!q.empty())
{
q.pop();
}
for (int i = 0; i < 25; i++)
{
if (next[0][i] != -1)
{
fail[next[0][i]] = 0;
q.push(next[0][i]);
}
}
while (!q.empty())
{
int u = q.front();
q.pop();
for (int i = 0; i < 25; i++)
{
if (next[u][i] != -1)
{
q.push(next[u][i]);
int tmp = fail[u];
while (tmp&&next[tmp][i]==-1)
{
tmp = fail[tmp];
}
tmp = next[tmp][i];
if (tmp == -1)
{
tmp = 0;
}
fail[next[u][i]] = tmp;
}
}
}
}
void query(string s)
{
cnt = 0;
int len = s.size();
int u = 0;
for (int i = 0; i < len; i++)
{
int c = s[i] - 'a';
while (next[u][c] == -1)
{
u = fail[u];
if (u == 0)
{
if (next[u][c] != -1)
u = next[u][c];
}
if (u == 0)
{
goto end;
}
}
u = next[u][c];
int tmp = u;
while (tmp != 0)
{
if (val[tmp] >= 0)
{
cnt += val[tmp];
val[tmp] = -1;
}
else
{
break;
}
tmp = fail[tmp];
}
end:;
}
}
}ac;
int main()
{
string s[4];
s[0] = "abcd";
s[1] = "abd";
s[2] = "bce";
s[3] = "cd";
ac.init();
for (int i = 0; i < 4; i++)
{
ac.insert(s[i]);
}
ac.build();
string p = "abcde";
ac.query(p);
cout << ac.cnt;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: