2013-team6/automaton
从 Trac 迁移的文章
这是从旧校内 Wiki 迁移的文章,可能存在一些样式问题,您可以向 memset0 反馈。
原文章内容如下:
{{{
初始化
ac.init()
插入
ac.insert(str)
找fail函数
ac.make()
匹配
ac.find()
index记状态
end记录有几个串结束
}}}
{{{
#include <iostream>
#include <queue>
using namespace std;
class Automaton{
public:
static const int MAXN=500010;
static const int LEAF=28;
int trie[MAXN][LEAF],fail[MAXN];
int end[MAXN];
int n;
void clear(int v){
memset(trie[v],0,sizeof(trie[v]));
index[v]=fail[v]=end[v]=0;
}
void init(){
clear(0);
n=1;
}
int idx(char ch){
return ch-'a';
}
void insert(const char* s,int value=0){
int v=0;
for (int x,i=0;s[i];i++){
x=idx(s[i]);
if (trie[v][x]==0){
clear(n);
trie[v][x]=n++;
}
v=trie[v][x];
}
//index[v]=1<<value;
end[v]++;
}
void make(){
queue<int> q;
for (int i=0;i<LEAF;i++)
if (trie[0][i]) q.push(trie[0][i]);
while (!q.empty()){
int v=q.front();q.pop();
//index[v]|=index[fail[v]];
for (int i=0;i<LEAF;i++){
int &p=trie[v][i];
if (p==0) p=trie[fail[v]][i];
else{
fail[p]=trie[fail[v]][i];
q.push(p);
}
}
}
}
int find(const char *s){
int v=0;
int ans=0;
for(int i=0; s[i]; i++){
int x=idx(s[i]);
v = trie[v][x];
int y=v;
while (y){
ans += end[y];
end[y] = 0;
y = fail[y];
}
//if (end[v]) printf("%d\n",i);
}
return ans;
}
}ac;
}}}
初始化
ac.init()
插入
ac.insert(str)
找fail函数
ac.make()
匹配
ac.find()
index记状态
end记录有几个串结束
#include <iostream>
#include <queue>
using namespace std;
class Automaton{
public:
static const int MAXN=500010;
static const int LEAF=28;
int trie[MAXN][LEAF],fail[MAXN];
int end[MAXN];
int n;
void clear(int v){
memset(trie[v],0,sizeof(trie[v]));
index[v]=fail[v]=end[v]=0;
}
void init(){
clear(0);
n=1;
}
int idx(char ch){
return ch-'a';
}
void insert(const char* s,int value=0){
int v=0;
for (int x,i=0;s[i];i++){
x=idx(s[i]);
if (trie[v][x]==0){
clear(n);
trie[v][x]=n++;
}
v=trie[v][x];
}
//index[v]=1<<value;
end[v]++;
}
void make(){
queue<int> q;
for (int i=0;i<LEAF;i++)
if (trie[0][i]) q.push(trie[0][i]);
while (!q.empty()){
int v=q.front();q.pop();
//index[v]|=index[fail[v]];
for (int i=0;i<LEAF;i++){
int &p=trie[v][i];
if (p==0) p=trie[fail[v]][i];
else{
fail[p]=trie[fail[v]][i];
q.push(p);
}
}
}
}
int find(const char *s){
int v=0;
int ans=0;
for(int i=0; s[i]; i++){
int x=idx(s[i]);
v = trie[v][x];
int y=v;
while (y){
ans += end[y];
end[y] = 0;
y = fail[y];
}
//if (end[v]) printf("%d\n",i);
}
return ans;
}
}ac;