首页 > 代码库 > HDU 2896 (AC自动机模板题)

HDU 2896 (AC自动机模板题)

题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=2896

题目大意:多个模式串。多个匹配串。其中串的字符范围是(0~127)。问匹配串中含有哪几个模式串。

解题思路

AC自动机模板题。注意一下字符范围。

cnt记录这个模式串的个数改为这个模式串的index。

find的时候,把找到的index压入vector里面即可。

注意有多个匹配串,每次find之后会把last->cnt修改,原因是防止一个模式串出现了多次被压入vector,所以先备份一下,再还原回来。

 

#include "cstdio"#include "cstring"#include "string"#include "iostream"#include "queue"#include "vector"#include "algorithm"using namespace std;#define maxn 130struct Trie{    Trie *next[maxn],*fail;    int cnt;}*root;struct status{    Trie *last;    int cnt;    status(Trie *last,int cnt):last(last),cnt(cnt) {}};Trie *newnode(){    Trie *ret=new Trie;    memset(ret->next,0,sizeof(ret->next));    ret->fail=0;    ret->cnt=0;    return ret;}void init() {root=newnode();}void Insert(string str,int index){    Trie *pos=root;    for(int i=0;i<str.size();i++)    {        int c=str[i];        if(!pos->next[c]) pos->next[c]=newnode();        pos=pos->next[c];    }    pos->cnt=index;}void getfail(){    queue<Trie *> Q;    for(int c=0;c<maxn;c++)    {        if(root->next[c])        {            root->next[c]->fail=root;            Q.push(root->next[c]);        }        else root->next[c]=root;    }    while(!Q.empty())    {        Trie *x=Q.front();Q.pop();        for(int c=0;c<maxn;c++)        {            if(x->next[c])            {                x->next[c]->fail=x->fail->next[c];                Q.push(x->next[c]);            }            else x->next[c]=x->fail->next[c];        }    }}vector<int> find(string str){    Trie *pos=root,*last;    queue<status> Q;    vector<int> ans;    for(int i=0;i<str.size();i++)    {        int c=str[i];last;        if(pos->next[c])        {            pos=pos->next[c];            last=pos;            while(last->cnt)            {                Q.push(status(last,last->cnt));                ans.push_back(last->cnt);                last->cnt=0; //修改last->cnt                last=last->fail;            }        }    }    while(!Q.empty()) //恢复last->cnt    {        status x=Q.front();Q.pop();        x.last->cnt=x.cnt;    }    return ans;}int main(){    //freopen("in.txt","r",stdin);    ios::sync_with_stdio(false);    int n,m;    string tt;    while(cin>>n)    {        init();        for(int i=1;i<=n;i++)        {            cin>>tt;            Insert(tt,i);        }        getfail();        cin>>m;        int cnt=0;        for(int i=1;i<=m;i++)        {            cin>>tt;            vector<int> ans=find(tt);            sort(ans.begin(),ans.end());            if(!ans.size()) continue;            cnt++;            printf("web %d:",i);            for(int j=0;j<ans.size();j++) printf(" %d",ans[j]);            printf("\n");        }        printf("total: %d\n",cnt);    }}

 

 

HDU 2896 (AC自动机模板题)