uva11019
来源:互联网 发布:php url 记录跳转设计 编辑:程序博客网 时间:2024/06/05 03:44
// UVa11019 Matrix Matcher// Rujia Liu#include<cstring>#include<queue>#include<cstdio>#include<map>#include<string>using namespace std;const int SIGMA_SIZE = 26;const int MAXNODE = 10000 + 10;void process_match(int pos, int v); // AC自动机每找到一个匹配会调用一次,结束位置为pos,val为vstruct AhoCorasickAutomata { int ch[MAXNODE][SIGMA_SIZE]; int f[MAXNODE]; // fail函数 int val[MAXNODE]; // 每个字符串的结尾结点都有一个非0的val int last[MAXNODE]; // 输出链表的下一个结点 int sz; void init() { sz = 1; memset(ch[0], 0, sizeof(ch[0])); } // 字符c的编号 int idx(char c) { return c-'a'; } // 插入字符串。v必须非0 void insert(char *s, int v) { 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; ch[u][c] = sz++; } u = ch[u][c]; } val[u] = v; } // 递归打印以结点j结尾的所有字符串 void report(int pos, int j) { if(j) { process_match(pos, val[j]); report(pos, last[j]); } } // 在T中找模板 int find(char* T) { 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]) report(i, j); else if(last[j]) report(i, last[j]); // 找到了! } } // 计算fail函数 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; } } // 按BFS顺序计算fail while(!q.empty()) { int r = q.front(); q.pop(); for(int c = 0; c < SIGMA_SIZE; c++) { int u = ch[r][c]; 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]]; } } }};AhoCorasickAutomata ac;const int maxn = 1000 + 10;const int maxm = 1000 + 10;const int maxx = 100 + 10;const int maxy = 100 + 10;char text[maxn][maxm], P[maxx][maxy];int repr[maxx]; // repr[i]为模板第i行的“代表元”int next[maxx]; // next[i]为模板中与第i行相等的下一个行编号int len[maxx]; // 模板各行的长度int tr; // 当前文本行编号int cnt[maxn][maxm];void process_match(int pos, int v) { int pr = repr[v - 1]; // 匹配到得模板行编号 int c = pos - len[pr] + 1; while(pr >= 0) { if(tr >= pr) // P的行pr出现在在T的tr行,起始列编号为c cnt[tr - pr][c]++; pr = next[pr]; }}int main() { int T, n, m, x, y; scanf("%d", &T); while(T--) { scanf("%d%d", &n, &m); for(int i = 0; i < n; i++) scanf("%s", text[i]); scanf("%d%d", &x, &y); ac.init(); for(int i = 0; i < x; i++) { scanf("%s", P[i]); len[i] = strlen(P[i]); repr[i] = i; next[i] = -1; for(int j = 0; j < i; j++) if(strcmp(P[i], P[j]) == 0) { repr[i] = j; next[i] = next[j]; next[j] = i; break; } if(repr[i] == i) ac.insert(P[i], i+1); } ac.getFail(); memset(cnt, 0, sizeof(cnt)); for(tr = 0; tr < n; tr++) ac.find(text[tr]); int ans = 0; for(int i = 0; i < n-x+1; i++) for(int j = 0; j < m-y+1; j++) if(cnt[i][j] == x) ans++; printf("%d\n", ans); } return 0;}
0 0
- uva11019
- Matrix Matcher UVA11019
- AC自动机 UVa11019
- UVa11019 Matrix Matcher
- uva11019 Matrix Matcher
- UVA11019 Matrix Matcher AC自动机
- [UVA11019] Matrix Matcher && AC自动机
- Uva11019——二维字符串匹配
- UVA11019----AC自动机(要深刻理解)*
- AC自动机(矩阵匹配)uva11019
- 【ac自动机】uva11468 Substring && uva11019 Matrix Matcher
- 例题3.16 矩阵匹配器 UVa11019
- UVa11019 Matrix Matcher 留坑[AC自动机]
- uva11019 - Matrix Matcher 二维矩阵匹配 AC自动机
- 【Uva11019】Matrix Matcher【AC自动机】【二维字符串匹配】
- Uva11019 AC自动机解决矩形模式串与文本串的匹配问题
- UVA11019 Matrix Matcher(一种计算子矩阵在母矩阵中出现次数的办法,AC自动机+kmp)
- 批处理实现SQLServer数据库备份与还原
- ORACLE 收缩表(shrink)简介
- OC -- 第一个类
- LeetCode Gray Code
- greenplum分布式数据仓库的基本介绍
- uva11019
- 51Talk-Level 7 Unit 4 L2
- BlueTooth的使用
- 最短路 - dijkstra - (一)
- Good Luck Charlie(听力恢复训练)
- [ubuntu]替换自带的更新源
- Java类的初始化
- HDOJ 4974 A simple water problem
- Node.Js 处理post数据