#include <iostream>
#define KIND 26
#define STR_MAX 1000
class AC_automation
{
struct tri_node
{
tri_node* fail;
tri_node* next[26];
bool flag;
tri_node()
{
fail=nullptr;
for(int i=0;i!=26;i++){
next[i]=nullptr;
}
flag=false;
}
};
typedef tri_node node_t;
public:
AC_automation()
{
root_=new node_t();
}
void insert_word(char* s)
{
size_t len=strlen(s);
size_t idx(0);
node_t* p=root_;
node_t* temp(nullptr);
for (int i= 0; i != len ; i++){
idx=s[i]-'a';
if(p->next[idx]==nullptr){
temp=new node_t();
p->next[idx]=temp;
}
p=p->next[idx];
}
p->flag=true;
}
size_t search(char* s)
{
int len=strlen(s);
if(abs(len)>STR_MAX){
return 0;
}
node_t * p=root_;
size_t idx(0);
size_t cnt(0);
for(int i=0;i!=len;i++){
idx=s[i]-'a';
while(p->next[idx]==NULL&&p!=root_){
p=p->fail;
}
p=p->next[idx];
if(p==nullptr){
p=root_;
}
node_t *temp=p;
while(temp!=root_ && temp->flag==true){
cnt++;
temp->flag=false;
temp=temp->fail;
}
}
return cnt;
}
~AC_automation()
{
clear_trie(root_);
}
public:
void build_ac_tree()
{
node_t* queue[1000];
memset(queue,0,sizeof(node_t*)*1000);
size_t head=NULL,tail=NULL;
queue[tail++]=root_;
root_->fail=nullptr;
node_t* p(nullptr);
node_t* temp(nullptr);
while(head!=tail){
p=queue[head++];
for(int i=0;i!=26;i++){
if(p->next[i]!=nullptr){
if(p==root_){
p->next[i]->fail=root_;
}else{
temp=p->fail;
while (temp!=NULL){
if(temp->next[i]!=NULL){
p->next[i]->fail=temp->next[i];
break;
}
temp=temp->fail;
}
if(temp==NULL) p->next[i]->fail=root_;
}
queue[tail++]=p->next[i];
}
}
}
}
void clear_trie(node_t* node)
{
if(node==nullptr){
return;
}
for(int i=0;i!=26;i++){
clear_trie(node->next[i]);
}
delete node;
}
private:
node_t* root_;
};
int main()
{
std::cout<<"ac_mation"<<std::endl;
char str[]="asherdsfggsoap";
char word1[]="her";
char word3[]="he";
char word2[]="gsoap";
AC_automation ac_auto;
ac_auto.insert_word(word1);
ac_auto.insert_word(word2);
ac_auto.insert_word(word3);
ac_auto.build_ac_tree();
size_t res= ac_auto.search(str);
std::cout<<res<<std::endl;
getchar();
}
AC自动机
最新推荐文章于 2024-06-18 12:51:06 发布