SPOJ6898 Substring Problem AC自动机

来源:互联网 发布:淘宝联盟靠谱吗 编辑:程序博客网 时间:2024/05/21 19:39

挺简单的AC自动机,只要求判断该串是否出现即可。只是有点坑,每一串可能出现多次。因此,要存储有哪一串序列序号的信息。

#include<stdio.h>  #include<string.h>  #include<queue>  #include<vector>using namespace std;#define maxn 110000int n,ch[maxn][52],fail[maxn],tot,root;int ans[maxn],biao[maxn];   char s[100010],fea[2010]; vector<int>val[maxn];//存储序号信息。queue<int>q;  int id(char t){if(t>='A'&&t<='Z')return t-'A';else return t-'a'+26;}int newnode()  {      memset(ch[tot],0,sizeof(ch[tot]));  val[tot].clear();      return tot++;  }  void updatea(char *a,int no)  {      int i,len=strlen(a),cur=root;      for(i=0;i<len;i++)      {          if(!ch[cur][id(a[i])])              ch[cur][id(a[i])]=newnode();          cur=ch[cur][id(a[i])];      }      val[cur].push_back(no);  biao[cur]=1;//用1有个好处:进行|运算。}    void getfail()  {      fail[root]=root;      for(int i=0;i<26;i++)          if(ch[root][i])          {              fail[ch[root][i]]=root;              q.push(ch[root][i]);          }      while(!q.empty())      {          int cur=q.front();          q.pop();          for(int i=0;i<26;i++)              if(!ch[cur][i])                  ch[cur][i]=ch[fail[cur]][i];              else              {                  fail[ch[cur][i]]=ch[fail[cur]][i];biao[ch[cur][i]]|=biao[fail[ch[cur][i]]];//需注意                q.push(ch[cur][i]);              }      }  }  void query()  {      int cur=root,i,len=strlen(s);      for(i=0;i<len;i++)      {cur=ch[cur][id(s[i])];                    int temp=cur;          while(temp!=root&&biao[temp])          {      biao[temp]=0;    for(int j=0;j<val[temp].size();j++)ans[val[temp][j]]=1;            temp=fail[temp];         }      }     }  int main()  {      while(~scanf("%s",s))      {          int i,j,k;          tot=0;memset(ans,0,sizeof(ans));        root=newnode();scanf("%d",&n);        for(i=1;i<=n;i++)          {              scanf("%s",&fea);              updatea(fea,i);        }          getchar();          getfail();          query();  for(i=1;i<=n;i++)if(ans[i])printf("Y\n");else printf("N\n");    }      return 0;  }


0 0
原创粉丝点击