UVa:11019 Matrix Matcher(AC自动机)
2014-03-12 09:52
399 查看
AC自动机。
很容易想到一个思路将模式矩阵的每一行插入Tire,然后将匹配矩阵的每一行用AC自动机漫游,统计该行中出现过的模式矩阵行,最后判断出现过的每行是否能够组成整个模式矩阵即可。这个也很好判断。开一个数组flag【i】【j】【k】表示字符【i,j】是第k个字符串的末尾
但是有个问题如果模式矩阵中的串有重复,比如说
匹配阵是
aaa
aaa
aaa
模式矩阵
aa
aa
那么很有可能得不到正确结果。
所以我把AC自动机中的val数组改成了二维,来表示某个字符可能是多个重复字符串的末尾。
注意是字符矩阵,所以只用26个小写字母是不行的。至少得128.
很容易想到一个思路将模式矩阵的每一行插入Tire,然后将匹配矩阵的每一行用AC自动机漫游,统计该行中出现过的模式矩阵行,最后判断出现过的每行是否能够组成整个模式矩阵即可。这个也很好判断。开一个数组flag【i】【j】【k】表示字符【i,j】是第k个字符串的末尾
但是有个问题如果模式矩阵中的串有重复,比如说
匹配阵是
aaa
aaa
aaa
模式矩阵
aa
aa
那么很有可能得不到正确结果。
所以我把AC自动机中的val数组改成了二维,来表示某个字符可能是多个重复字符串的末尾。
注意是字符矩阵,所以只用26个小写字母是不行的。至少得128.
#include <iostream> #include <cstdio> #include <cstring> #include <string> #include <vector> #include <queue> #include <set> #include <map> #include <algorithm> #define ll long long #define INF 2139062143 #define inf -2139062144 #define MOD 20071027 #define MAXN 101*100 #define LIM 128 using namespace std; char gl1[1005][1005],gl2[105][105]; bool flag[1005][1005][101]; int now,ans; int nx,ny,mx,my; struct Tire { int ch[MAXN][LIM],last[MAXN],f[MAXN]; vector<int> val[MAXN]; int sz; void clear() { sz=1; memset(ch[0],0,sizeof(ch[0])); val[0].clear(); } void insert(char *word,int v) { int u=0; for(int i=0; word[i]; ++i) { int c=word[i]; if(!ch[u][c]) { memset(ch[sz],0,sizeof(ch[sz])); val[sz].clear(); ch[u][c]=sz++; } u=ch[u][c]; } val[u].push_back(v); } void process(int i,int j) { if(j) { for(int k=0; k<val[j].size(); ++k) { int v=val[j][k]; if(v==1||flag[now-1][i+1][v-1]==true) { flag[now][i+1][v]=true; if(v==mx) ans++; } } process(i,last[j]); } } void find(char *str) { int j=0; for(int i=0; str[i]; ++i) { int c=str[i]; j=ch[j][c]; if(val[j].size()) process(i,j); else if(last[j]) process(i,last[j]); } } void getFail() { f[0]=0; queue<int> que; for(int i=0; i<LIM; ++i) { int u=ch[0][i]; if(u) { f[u]=0; last[u]=0; que.push(u); } } while(!que.empty()) { int q=que.front(); que.pop(); for(int i=0; i<LIM; ++i) { int u=ch[q][i], v=f[q]; if(!u) { ch[q][i]=ch[v][i]; continue; } que.push(u); while(v&&!ch[v][i]) v=ch[v][i]; f[u]=ch[v][i]; last[u]=val[f[u]].size()?f[u]:last[f[u]]; } } } }; Tire tree; int main() { int T; scanf("%d",&T); while(T--) { tree.clear(); scanf("%d%d",&nx,&ny); for(int i=1; i<=nx; ++i) { scanf("%s",gl1[i]+1); memset(flag[i],0,sizeof(flag[i])); } scanf("%d%d",&mx,&my); for(int i=1; i<=mx; ++i) { scanf("%s",gl2[i]+1); tree.insert(gl2[i]+1,i); } tree.getFail(); ans=0; for(int i=1; i<=nx; ++i) { now=i; tree.find(gl1[i]+1); } printf("%d\n",ans); } return 0; }
相关文章推荐
- UVA 11019 Matrix Matcher(AC自动机)
- UVA-11019Matrix Matcher(AC自动机)
- uva 11019 Matrix Matcher (ac自动机二维匹配)
- UVA-11019 - Matrix Matcher(AC自动机)
- uva 11019 - Matrix Matcher(AC自动机)
- UVA 11019 Matrix Matcher(ac自动机)
- UVA 11019(Matrix Matcher-vector从迭代器中取值,AC自动机匹配字符矩阵)
- UVA 11019 Matrix Matcher(AC自动机:矩阵匹配)
- UVA-11019 - Matrix Matcher(AC自动机)
- UVA 1019 Matrix Matcher(AC自动机)
- [UVA11019] Matrix Matcher && AC自动机
- UVA 11019 Matrix Matcher AC自动机字符串矩阵匹配
- UVA 1449 Dominating Patterns(AC自动机)
- UVA 1399 - Puzzle(AC自动机+DP)
- UVA 1076 - Password Suspects(AC自动机+DP)
- uva 11019 - Matrix Matcher --AC自动机
- UVa 11468 AC自动机+记忆化搜索
- UVA11019 Matrix Matcher (AC自动机)
- UVA 11019 Matrix Matcher (hash+kmp)
- UVA11019 Matrix Matcher