AC自动机算法学习示例代码
#include<iostream>
using namespace std;
#include<vector>
#include<algorithm>
#include<string>
#include<queue>
string m[5]={"he", "she", "hers", "his", "is"};
string s="ahishersheishiser";
struct node
{
node *child[26];
node *fail;
vector<int> exist;
node()
{
fail=NULL;
for(int i=0;i<26;i++)
{
child[i]=NULL;
}
}
};
//字典树中插入元素
void ac_insert(node *root,int t)
{
node *tmp=root;
string s_now=m[t];
for(int i=0;i<s_now.length();i++)
{
int c=s_now[i]-'a';
if(tmp->child[c]==NULL)
{
tmp->child[c]=new node();
}
tmp=tmp->child[c];
}
tmp->exist.push_back(s_now.length());
}
void ac_build(node *root)
{
// node *tmp=root;
//建字典树
for(int i=0;i<5;i++)
{
ac_insert(root,i);
}
queue<node *> q;
for(int i=0;i<26;i++)
{
if(root->child[i])
{
root->child[i]->fail=root;
q.push(root->child[i]);
}
}
//构建fail指针
while(!q.empty())
{
node *tmp=q.front();q.pop();
for(int i=0;i<26;i++)
{
if(tmp->child[i])
{
node *y=tmp->child[i];
node *fafail=tmp->fail;
while(fafail && NULL == fafail->child[i])
fafail=fafail->fail;
if(fafail==NULL) y->fail=root;
else y->fail=fafail->child[i];
if(y->fail->exist.size())
{
for(int j=0;j<y->fail->exist.size();j++)
y->exist.push_back(y->fail->exist[j]);
}
q.push(y);
}
}
}
}
void ac_print(int start,int len)
{
for(int i=0;i<start;i++) cout<<" ";
for(int i=start;i<start+len;i++) cout<<s[i];
cout<<endl;
}
void ac_query(node *root)
{
node *tmp=root;
for(int i=0;i<s.length();i++)
{
int c=s[i]-'a';
while(tmp->child[c]==NULL && tmp->fail!=NULL)
tmp=tmp->fail;
if(tmp->child[c]) tmp=tmp->child[c];
else continue;
if(tmp->exist.size())
{
for(int j=0;j<tmp->exist.size();j++)
ac_print(i+1-tmp->exist[j],tmp->exist[j]);
}
}
}
int main()
{
node *root=new node();
ac_build(root);
cout<<s<<endl;
ac_query(root);
return 0;
}