首页 > 代码库 > AC自动机模板

AC自动机模板

*和?的通配符问题

对应题目  FJUTOJ2579

  1 #include<stdio.h>
  2 #include<string.h>
  3 #include<algorithm>
  4 #include<queue>
  5 #include<vector>
  6 using namespace std;
  7 const int maxn=100050;
  8 const int maxsig=26;
  9 vector<int>vec[maxn];
 10 struct Aho
 11 {
 12     struct node
 13     {
 14         int next[maxsig];
 15         int fail;
 16     } stateTable[maxn];
 17     int cnt[maxn];
 18     int size,tcnt;
 19     queue<int>q;
 20     void init()
 21     {
 22         while(!q.empty())q.pop();
 23         memset(stateTable[0].next,0,sizeof(stateTable[0].next));
 24         vec[0].clear();
 25         size=1;
 26         tcnt=0;
 27     }
 28     int getid(char c)
 29     {
 30         return c-a;
 31     }
 32     void insert(char *s)
 33     {
 34         int n=strlen(s);
 35         int now=0;
 36         init();
 37         for(int i=0;!i||s[i-1]; i++)
 38         {
 39             if(s[i]==?||s[i]==0)
 40             {
 41                 if(now)
 42                 {
 43                     vec[now].push_back(i-1);
 44                     now=0;
 45                     tcnt++;
 46                 }
 47                 continue;
 48             }
 49             else
 50             {
 51                 int c=getid(s[i]);
 52                 if(!stateTable[now].next[c])
 53                 {
 54                     memset(stateTable[size].next,0,sizeof(stateTable[size].next));
 55                     vec[size].clear();
 56                     stateTable[now].next[c]=size++;
 57                 }
 58                 now=stateTable[now].next[c];
 59             }
 60         }
 61     }
 62     void build()
 63     {
 64         stateTable[0].fail=-1;
 65         q.push(0);
 66         while(!q.empty())
 67         {
 68             int u=q.front();
 69             q.pop();
 70             for(int i=0; i<maxsig; i++)
 71                 if(stateTable[u].next[i])
 72                 {
 73                     int v=stateTable[u].fail;
 74                     while(v!=-1)
 75                     {
 76                         if(stateTable[v].next[i])
 77                         {
 78                             stateTable[stateTable[u].next[i]].fail=stateTable[v].next[i];
 79                             break;
 80                         }
 81                         v=stateTable[v].fail;
 82                     }
 83                     if(v==-1)stateTable[stateTable[u].next[i]].fail=0;
 84                     q.push(stateTable[u].next[i]);
 85                     int x=stateTable[u].next[i];
 86                     if(vec[stateTable[x].fail].size())
 87                     {
 88                         vec[x].insert(vec[x].begin(),vec[stateTable[x].fail].begin(),vec[stateTable[x].fail].end());
 89                     }
 90                 }
 91         }
 92     }
 93     int match(char *s)
 94     {
 95         if(tcnt==0)return 0;
 96         int n=strlen(s);
 97         int now=0;
 98         for(int i=0; i<n; i++)
 99         {
100             cnt[i]=0;
101             int c=getid(s[i]);
102             if(stateTable[now].next[c])
103                 now=stateTable[now].next[c];
104             else
105             {
106                 int v=stateTable[now].fail;
107                 while(v!=-1&&!stateTable[v].next[c])
108                     v=stateTable[v].fail;
109                 if(v==-1)now=0;
110                 else now=stateTable[v].next[c];
111             }
112             for(int j=0; j<vec[now].size(); j++)
113             {
114                 if(i>=vec[now][j])
115                 {
116                     cnt[i-vec[now][j]]++;
117                     if(cnt[i-vec[now][j]]==tcnt) return i-vec[now][j];
118                 }
119             }
120         }
121         return -1;
122     }
123 } aho;
124 char s1[100010],s2[100010],tmp[100010];
125 
126 int solve(char *s1,char *s2)
127 {
128     int l1=strlen(s1),l2=strlen(s2);
129     int tl=0;
130     for(int i=0; i<l2; i++)if(s2[i]!=*)tl++;
131     if(tl>l1)return 0;
132     int s=-1;
133     for(int i=0;i==0||s1[i-1]; i++)
134     {
135         if(s1[i]==s2[i]||(s1[i]!=0&&s2[i]==?))continue;
136         if(s2[i]==*)s=i+1;
137         else return 0;
138         break;
139     }
140     if(s==-1)return 1;
141     for(int i=l1-1,j=l2-1;; i--,j--)
142     {
143         if(i==-1&&j==-1)break;
144         if(i==-1)
145         {
146             if(s2[j]!=*)return 0;
147             break;
148         }
149         if(j==-1)return 0;
150         if(s1[i]==s2[j]||s2[j]==?)
151         {
152             s1[l1=i]=s2[j]=0;
153         }
154         else if(s2[j]==*)break;
155         else return 0;
156     }
157     int ts=s-1;
158     for(int i=1; i<l2-tl; i++)
159     {
160         if(s2[s]==*)
161         {
162             s++;
163             continue;
164         }
165         int len=0;
166         for(; s2[s]!=*&&s2[s]; s++)
167         {
168             tmp[len]=s2[s];
169             tmp[++len]=0;
170         }
171         s++;
172         aho.insert(tmp);
173         aho.build();
174         int pos=aho.match(s1+ts);
175         if(pos==-1)return 0;
176         else
177         {
178             ts+=pos+len;
179             if(ts>l1)return 0;
180         }
181     }
182     return 1;
183 }
184 int main()
185 {
186     while(~scanf("%s%s",s1,s2))
187     {
188         aho.init();
189         if(solve(s1,s2))
190             printf("YES\n");
191         else printf("NO\n");
192     }
193     return 0;
194 }

病毒侵袭FJUTOJ2581

  1 #include<stdio.h>
  2 #include<string.h>
  3 #include<algorithm>
  4 #include<queue>
  5 #include<vector>
  6 using namespace std;
  7 vector<int>vs[1111];
  8 const int maxn=100050;
  9 const int maxsig=128;
 10 struct Aho
 11 {
 12     struct node
 13     {
 14         int next[maxsig];
 15         int fail,cnt;
 16     } stateTable[maxn];
 17     int size;
 18     queue<int>q;
 19     void init()
 20     {
 21         while(!q.empty())q.pop();
 22         memset(stateTable[0].next,0,sizeof(stateTable[0].next));
 23         stateTable[0].cnt=0;
 24         size=1;
 25     }
 26     int getid(char c)
 27     {
 28         return c;
 29     }
 30     void insert(char *s,int x)
 31     {
 32         int n=strlen(s);
 33         int now=0;
 34         for(int i=0; i<n; i++)
 35         {
 36             int c=getid(s[i]);
 37             if(!stateTable[now].next[c])
 38             {
 39                 memset(stateTable[size].next,0,sizeof(stateTable[size].next));
 40                 stateTable[size].cnt=0;
 41                 stateTable[now].next[c]=size++;
 42             }
 43             now=stateTable[now].next[c];
 44         }
 45         stateTable[now].cnt=x;
 46     }
 47     void build()
 48     {
 49         stateTable[0].fail=-1;
 50         q.push(0);
 51         while(!q.empty())
 52         {
 53             int u=q.front();
 54             q.pop();
 55             for(int i=0; i<maxsig; i++)
 56                 if(stateTable[u].next[i])
 57                 {
 58                     int v=stateTable[u].fail;
 59                     while(v!=-1)
 60                     {
 61                         if(stateTable[v].next[i])
 62                         {
 63                             stateTable[stateTable[u].next[i]].fail=stateTable[v].next[i];
 64                             break;
 65                         }
 66                         v=stateTable[v].fail;
 67                     }
 68                     if(v==-1)stateTable[stateTable[u].next[i]].fail=0;
 69                     q.push(stateTable[u].next[i]);
 70                 }
 71         }
 72     }
 73     void Get(int u,int i)
 74     {
 75         while(u!=-1)
 76         {
 77             if(stateTable[u].cnt)
 78                 vs[i].push_back(stateTable[u].cnt);
 79             u=stateTable[u].fail;
 80         }
 81     }
 82     void match(char *s,int x)
 83     {
 84         int n=strlen(s);
 85         int now=0;
 86         for(int i=0; i<n; i++)
 87         {
 88             int c=getid(s[i]);
 89             if(stateTable[now].next[c])
 90                 now=stateTable[now].next[c];
 91             else
 92             {
 93                 int v=stateTable[now].fail;
 94                 while(v!=-1&&!stateTable[v].next[c])
 95                     v=stateTable[v].fail;
 96                 if(v==-1)now=0;
 97                 else now=stateTable[v].next[c];
 98             }
 99             if(stateTable[now].cnt)
100             Get(now,x);
101             else if(stateTable[now].fail)Get(stateTable[now].fail,x);
102         }
103     }
104 } aho;
105 char s[10010];
106 int main()
107 {
108     int n;
109     while(~scanf("%d",&n))
110     {
111         aho.init();
112         for(int i=1; i<=n; i++)
113             scanf("%s",s),aho.insert(s,i),vs[i].clear();
114         aho.build();
115         int m;
116         scanf("%d",&m);
117         for(int i=1; i<=m; i++)
118             scanf("%s",s),aho.match(s,i);
119         int ans=0;
120         for(int i=1; i<=m; i++)
121         {
122             if(vs[i].size())
123             {
124                 sort(vs[i].begin(),vs[i].end());
125                 vs[i].erase(unique(vs[i].begin(),vs[i].end()),vs[i].end());
126                 printf("web %d:",i);
127                 for(int j=0; j<vs[i].size(); j++)
128                     printf(" %d",vs[i][j]);
129                 printf("\n");
130                 ans++;
131             }
132         }
133         printf("total: %d\n",ans);
134     }
135     return 0;
136 }

病毒侵袭持续中 FJUTOJ2582

  1 #include<stdio.h>
  2 #include<string.h>
  3 #include<algorithm>
  4 #include<queue>
  5 #include<vector>
  6 using namespace std;
  7 const int maxn=100050;
  8 const int maxsig=128;
  9 struct Aho
 10 {
 11     struct node
 12     {
 13         int next[maxsig];
 14         int fail,cnt;
 15     } stateTable[maxn];
 16     int ans[10001];
 17     int size;
 18     queue<int>q;
 19     void init()
 20     {
 21         while(!q.empty())q.pop();
 22         memset(ans,0,sizeof(ans));
 23         memset(stateTable[0].next,0,sizeof(stateTable[0].next));
 24         stateTable[0].cnt=0;
 25         size=1;
 26     }
 27     int getid(char c)
 28     {
 29         return c;
 30     }
 31     void insert(char *s,int res)
 32     {
 33         int n=strlen(s);
 34         int now=0;
 35         for(int i=0; i<n; i++)
 36         {
 37             int c=getid(s[i]);
 38             if(!stateTable[now].next[c])
 39             {
 40                 memset(stateTable[size].next,0,sizeof(stateTable[size].next));
 41                 stateTable[size].cnt=0;
 42                 stateTable[now].next[c]=size++;
 43             }
 44             now=stateTable[now].next[c];
 45         }
 46         stateTable[now].cnt=res;
 47     }
 48     void build()
 49     {
 50         stateTable[0].fail=-1;
 51         q.push(0);
 52         while(!q.empty())
 53         {
 54             int u=q.front();
 55             q.pop();
 56             for(int i=0; i<maxsig; i++)
 57                 if(stateTable[u].next[i])
 58                 {
 59                     int v=stateTable[u].fail;
 60                     while(v!=-1)
 61                     {
 62                         if(stateTable[v].next[i])
 63                         {
 64                             stateTable[stateTable[u].next[i]].fail=stateTable[v].next[i];
 65                             break;
 66                         }
 67                         v=stateTable[v].fail;
 68                     }
 69                     if(v==-1)stateTable[stateTable[u].next[i]].fail=0;
 70                     q.push(stateTable[u].next[i]);
 71                 }
 72         }
 73     }
 74     void Get(int u)
 75     {
 76         int res=0;
 77         while(u!=-1)
 78         {
 79             if(stateTable[u].cnt)
 80                 ans[stateTable[u].cnt]++;
 81             u=stateTable[u].fail;
 82         }
 83     }
 84     int match(char *s)
 85     {
 86         int n=strlen(s);
 87         int now=0;
 88         for(int i=0; i<n; i++)
 89         {
 90             int c=getid(s[i]);
 91             if(stateTable[now].next[c])
 92                 now=stateTable[now].next[c];
 93             else
 94             {
 95                 int v=stateTable[now].fail;
 96                 while(v!=-1&&!stateTable[v].next[c])
 97                     v=stateTable[v].fail;
 98                 if(v==-1)now=0;
 99                 else now=stateTable[v].next[c];
100             }
101             Get(now);
102         }
103     }
104 }aho;
105 char ss[1001][51];
106 char s[2000001];
107 int main()
108 {
109     int n;
110     while(~scanf("%d",&n))
111     {
112         aho.init();
113         for(int i=1;i<=n;i++)
114         {
115             scanf("%s",ss[i]);
116             aho.insert(ss[i],i);
117         }
118         aho.build();
119         scanf("%s",s);
120         aho.match(s);
121         for(int i=1;i<=n;i++)
122             if(aho.ans[i])
123                 printf("%s: %d\n",ss[i],aho.ans[i]);
124     }
125     return 0;
126 }

 

AC自动机模板