您的位置:首页 > 其它

UVA 11019 Matrix Matcher 矩阵匹配器 AC自动机 二维文本串查找二维模式串

2017-09-12 10:13 357 查看
链接:https://vjudge.net/problem/UVA-11019
lrjP218 matrix matcher
#include<bits/stdc++.h>
using namespace std;
#define P pair<int,int>
#define ms(x,y) memset(x,y,sizeof x)
#define LL long long
const int maxn = 22;
const int mod = 1e9+7;
const int maxnode = 100*100+10;
const int sigma_size = 26;
vector<int> as[maxnode];
int cnt[1005][1005], ans;
int n, m, x, y;
struct AhoCorasickAutomata
{
int ch[maxnode][sigma_size];
int val[maxnode];
int sz;
int f[maxnode];
int last[maxnode];
void clear(){sz = 1; memset(ch[0],0,sizeof ch[0]); }
int idx(char c){return c-'a'; }

void insert(char *s,int x)
{
int u = 0, n = strlen(s);
for(int i = 0; i < n; i++){
int c = idx(s[i]);
if(!ch[u][c]){
memset(ch[sz], 0, sizeof ch[sz]);
val[sz] = 0;
as[sz].clear();
ch[u][c] = sz++;
}
u = ch[u][c];
}
as[u].push_back(x);///存储给字符结尾,有哪些行是终点。
val[u] = 1;
}

void find(char *T,int row){
int n = strlen(T);
int j = 0;
for(int i = 0; i < n; i++){
int c = idx(T[i]);
//while(j&&!ch[j][c]) j = f[j];
j = ch[j][c];
if(val[j]) print(j,i,row);
else if(last[j]) print(last[j],i,row);
}
}

void print(int j,int col,int row)
{
if(j){
//cnt[val[j]]++;
int len = as[j].size();
for(int i = 0; i < len; i++){
if(row-as[j][i]>=0){///cnt[row-as[j][i]][col]++这样当前找到的行,不会对自己起作用。而是对以前的起作用。
if(++cnt[row-as[j][i]][col]==x){///因为时间卡的紧,所以我没有在最外面判断。
///在这里判断节约时间。否则超时。
ans++;
}

}
}
print(last[j],col,row);
}
}

void getFail(){
queue<int> q;
f[0] = 0;
for(int c = 0; c < sigma_size; c++){
int u = ch[0][c];
if(u){f[u] = 0; q.push(u); last[u] = 0;}
}

while(!q.empty()){
int r = q.front(); q.pop();
for(int c = 0; c < sigma_size; c++){
int u = ch[r][c];
if(!u){
ch[r][c] = ch[f[r]][c]; continue;
}//if(!u) continue;
q.push(u);
int v = f[r];
while(v&&!ch[v][c]) v = f[v];
f[u] = ch[v][c];
last[u] = val[f[u]] ? f[u] : last[f[u]];
}
}
}

} ac ;
char t[1005][1005];
char s[105];
int main()
{
int T;
cin>>T;
while(T--)
{
scanf("%d%d",&n,&m);
ms(cnt,0);
ac.clear();
for(int i = 0; i < n; i++){
scanf("%s",t[i]);
}
scanf("%d%d",&x,&y);
for(int i = 0; i < x; i++){
scanf("%s",s);
ac.insert(s,i);
}
ac.getFail();
ans = 0;
for(int i = 0; i < n; i++){
ac.find(t[i],i);
}
cout<<ans<<endl;
}
return 0;
}

/*
2
1 1
x
1 1
y
3 3
abc
bcd
cde
2 2
bc
cd

*/
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: