UVa 11019 (AC自动机 二维模式串匹配) Matrix Matcher
2015-04-05 20:47
197 查看
就向书上说得那样,如果模式串P的第i行出现在文本串T的第r行第c列,则cnt[r-i][c]++;
还有个很棘手的问题就是模式串中可能会有相同的串,所以用repr[i]来记录第i个模式串P[i]第一次出现的位置。如果repr[i] == i,说明这个模式串之前没有重复过,可以加进自动机里去。有重复的话,把这些重复的模式串组织成一个链表,用next把它们连接起来。
所以在统计cnt的时候,匹配到的模式串可能会作为匹配的第i行,也可能是next[i]行,next[next[i]]行等等。
还有个很棘手的问题就是模式串中可能会有相同的串,所以用repr[i]来记录第i个模式串P[i]第一次出现的位置。如果repr[i] == i,说明这个模式串之前没有重复过,可以加进自动机里去。有重复的话,把这些重复的模式串组织成一个链表,用next把它们连接起来。
所以在统计cnt的时候,匹配到的模式串可能会作为匹配的第i行,也可能是next[i]行,next[next[i]]行等等。
#include <cstdio> #include <cstring> #include <queue> using namespace std; int n, m, x, y, tr; const int maxx = 100 + 10; const int maxn = 1000 + 10; const int maxnode = 10000 + 10; const int sigma_size = 26; char T[maxn][maxn], P[maxx][maxx]; int cnt[maxn][maxn]; int repr[maxx]; int next[maxx]; struct AhoCorasickAutomata { int ch[maxnode][sigma_size]; int f[maxnode]; int last[maxnode]; int val[maxnode]; int sz; void init() { sz = 1; memset(ch[0], 0, sizeof(ch[0])); } inline int idx(char c) { return c - 'a'; } 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; } void match(int i, int j) { int c = i - y + 1; int pr = repr[val[j] - 1]; while(pr >= 0) { if(tr - pr >= 0) cnt[tr-pr][c]++; pr = next[pr]; } } void print(int i, int j) {//在文本串的第i列匹配到单词节点j if(j) { match(i, j); print(i, last[j]); } } void find(char* T) { int j = 0, n = strlen(T); 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(i, j); else if(val[last[j]]) print(i, last[j]); } } 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; last[u] = 0; q.push(u); } } 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]]; } } } }ac; int main() { //freopen("in.txt", "r", stdin); int test; scanf("%d", &test); while(test--) { scanf("%d%d", &n, &m); for(int i = 0; i < n; i++) scanf("%s", T[i]); scanf("%d%d", &x, &y); ac.init(); for(int i = 0; i < x; i++) { repr[i] = i; next[i] = -1; scanf("%s", P[i]); 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(T); int ans = 0; for(int i = 0; i < n; i++) for(int j = 0; j < m; j++) if(cnt[i][j] == x) ans++; printf("%d\n", ans); } return 0; }
代码君相关文章推荐
- UVA 11019 Matrix Matcher 矩阵匹配器 AC自动机 二维文本串查找二维模式串
- 【Uva11019】Matrix Matcher【AC自动机】【二维字符串匹配】
- UVA 11019 Matrix Matcher(二维矩阵匹配ac自动机)
- Uva 11019 Matrix Matcher(二维字符串匹配)
- AC自动机(二维) UVA 11019 Matrix Matcher
- uva11019 - Matrix Matcher 二维矩阵匹配 AC自动机
- UVA 11019 Matrix Matcher( 二维字符匹配 AC自动机 + DP)
- UVA - 11019 Matrix Matcher (AC自动机(二维匹配) + dp)
- UVA 11019 Matrix Matcher——AC自动机
- UVA 11019 - Matrix Matcher(AC自动机 | hash大法)
- 矩阵匹配 AC自动机 或 二维Hash UVa 11019 - Matrix Matcher
- UVA 11019 二维匹配 AC自动机
- AC自动机(Matrix Matcher,UVA 11019)
- uva 11019 - Matrix Matcher --AC自动机
- 【ac自动机】uva11468 Substring && uva11019 Matrix Matcher
- UVa11019 Matrix Matcher 留坑[AC自动机]
- Uva11019——二维字符串匹配
- uva 11019 Matrix Matcher (ac自动机二维匹配)
- 多模式串匹配之AC自动机算法(Aho-Corasick算法)简介与C语言程序实现源码参考
- AC自动机(矩阵匹配)uva11019