题意:预先给你一些单词,然后给你一个字符串,在判断有多少个单词出现在这个字符串中。
分析:使用AC自动机解决。下面是自己写的类模版。可以直接使用。最后记得释放内存。
#include<iostream>
#include<queue>
using namespace std;
#define LETTER_COUNT 26
class AC_Automation
{
private:
struct Node
{
Node* fail; //失败指针
Node* next[LETTER_COUNT]; //Tire树节点的子节点
int count; //是否为该单词的最后一个节点
Node()
{
fail=NULL;
count=0;
memset(next,NULL,sizeof(next));
}
};
Node* m_sroot;
void Delete(Node* p);
public:
AC_Automation(){ m_sroot=(Node*)new Node();}
~AC_Automation(){ Delete(m_sroot);}
void AddWord(char* str); //添加一个单词
void Build_AC_Automation();
int GetMatchingCount(char* str);
};
int AC_Automation::GetMatchingCount(char* str)
{
int cnt=0,index;
Node* p,*temp;
p=m_sroot;
while(*str)
{
index=*str-'a';
while(p->next[index]==NULL && p!=m_sroot) p=p->fail;
p=p->next[index];
p=(p==NULL)?m_sroot:p;
temp=p;
while(temp!=m_sroot && temp->count!=-1) //确保当前字符前面包含的所有单词都被匹配
{
cnt+=temp->count;
temp->count=-1;
temp=temp->fail;
}
str++;
}
return cnt;
}
void AC_Automation::Delete(Node* p)
{
for(int i=0;i<LETTER_COUNT;i++)
if(p->next[i]!=NULL)
Delete(p->next[i]);
delete p;
}
void AC_Automation::Build_AC_Automation()
{
int i;
Node *temp,*p;
queue<Node*> q; //队列,用于BFS,建立失败指针
m_sroot->fail=NULL;
q.push(m_sroot);
while(!q.empty())
{
temp=q.front();
q.pop();
p=NULL;
for(i=0;i<LETTER_COUNT;i++)
{
if(temp->next[i]!=NULL)
{
if(temp==m_sroot) temp->next[i]->fail=m_sroot;
else
{
p=temp->fail;
while(p!=NULL)
{
if(p->next[i]!=NULL)
{
temp->next[i]->fail=p->next[i];
break;
}
p=p->fail;
}
if(p==NULL) temp->next[i]->fail=m_sroot;
}
q.push(temp->next[i]); //子节点如队列
}
}
}
}
void AC_Automation::AddWord(char* str)
{
Node* p=m_sroot;
int i=0;
int index;
while(*str)
{
index=*str-'a';
if(p->next[index]==NULL) p->next[index]=(Node*)new Node();
p=p->next[index];
str++;
}
p->count++; //单词的最后一个节点加1,单表新加入一个单词
}
int main()
{
int T,N,i;
char a[51];
char b[1000001];
cin>>T;
while(T--)
{
AC_Automation ac_auto;
cin>>N;
for(i=0;i<N;i++)
{
cin>>a;
ac_auto.AddWord(a);
}
ac_auto.Build_AC_Automation();
cin>>b;
cout<<ac_auto.GetMatchingCount(b)<<endl;
}
return 0;
}
原文地址:http://blog.csdn.net/a809146548/article/details/45244831