POJ 3167 Cow Patterns(模式串浮动匹配)
2015-04-30 14:18
375 查看
题目链接:http://poj.org/problem?id=3167
题意:模式串可以浮动的模式匹配问题给出模式串的相对大小,需要找出模式串匹配次数和位置。
思路:统计比当前数小,和于当前数相等的,然后进行kmp。
比如说模式串:1,4,4,2,3,1 而主串:5,6,2,10,10,7,3,2,9,那么2,10,10,7,3,2就是匹配的
code:
题意:模式串可以浮动的模式匹配问题给出模式串的相对大小,需要找出模式串匹配次数和位置。
思路:统计比当前数小,和于当前数相等的,然后进行kmp。
比如说模式串:1,4,4,2,3,1 而主串:5,6,2,10,10,7,3,2,9,那么2,10,10,7,3,2就是匹配的
code:
#include <cstdio> #include <cstring> #include <vector> using namespace std; const int MAXN = 100005; const int MAXM = 25005; int a[MAXN]; // 存放主串 int b[MAXM]; // 存放模式串 int as[MAXN][30]; // as[i][j] = k表示0 - i位中有k个数字j int bs[MAXM][30]; // bs[i][j] = k表示0 - i位中有k个数字j int next[MAXM]; // 存放模式串失配时的移动位数 vector<int> ans; // 存放结果 int n, m, s; void Init() { ans.clear(); memset(as, 0, sizeof(as)); memset(bs, 0, sizeof(bs)); as[1][a[1]] = 1; bs[1][b[1]] = 1; for (int i = 2; i <= n; ++i) { memcpy(as[i], as[i - 1], sizeof(as[0])); ++as[i][a[i]]; } for (int i = 2; i <= m; ++i) { memcpy(bs[i], bs[i - 1], sizeof(bs[0])); ++bs[i][b[i]]; } } void GetNext() { memset(next, 0, sizeof(next)); int i = 1, j = 0, k = 0; next[1] = 0; while (i <= m) { int si = 0, sj = 0, ei = 0, ej = 0; for (k = 1; k < b[i]; ++k) si += bs[i][k] - bs[i - j][k]; ei = bs[i][k] - bs[i - j][k]; for (k = 1; k < b[j]; ++k) sj += bs[j][k]; ej = bs[j][k]; if (0 == j || (si == sj && ei == ej)) next[++i] = ++j; else j = next[j]; } } void Kmp() { int i = 1, j = 1, k = 1; while (i <= n) { int si = 0, sj = 0, ei = 0, ej = 0; for (k = 1; k < a[i]; ++k) si += as[i][k] - as[i - j][k]; ei = as[i][k] - as[i - j][k]; for (k = 1; k < b[j]; ++k) sj += bs[j][k]; ej = bs[j][k]; if (0 == j || (si == sj && ei == ej)) ++i, ++j; else j = next[j]; if (j == m + 1) { ans.push_back(i - m); j = next[j]; } } } int main() { while (scanf("%d %d %d", &n, &m, &s) == 3) { for (int i = 1; i <= n; ++i) scanf("%d", &a[i]); for (int i = 1; i <= m; ++i) scanf("%d", &b[i]); Init(); GetNext(); Kmp(); size_t len = ans.size(); printf("%d\n", len); for (size_t i = 0; i < len; ++i) printf("%d\n", ans[i]); } return 0; }
相关文章推荐
- poj 1816 Trie+DFS匹配模式串
- (串的模式匹配4.6.2)POJ 3461 Oulipo(KMP算法的应用——求一个单词在一行文本中的出现次数)
- (字符串模式匹配4.7.10)POJ 2192 Zipper(判断第3个字符串能否有前两个字符串组成)
- POJ 3167 Cow Patterns
- poj 3167 Cow Patterns(kmp)
- POJ 3461 Oulipo(自己YY的模式匹配算法)
- POJ 3461(模式匹配数&覆盖函数)
- POJ 3167 Cow Patterns 笔记
- POJ 3167 Cow Patterns
- 【POJ 3167】Cow Patterns (KMP+树状数组)
- Bzoj 1729 [Usaco2005 dec] Cow Patterns 牛的模式匹配
- (字符串的模式匹配4.7.12)POJ 2121 Inglish-Number Translator(将英文数字转换成阿拉伯数字)
- poj 3461 KMP(模式匹配模板)
- 字符串模式匹配:POJ 3461 Oulipo
- POJ 3167 Cow Patterns (KMP + 树状数组)
- (字符串的模式匹配4.7.18)POJ 2406 Power Strings(求一个字符串的最小重复串)
- (字符串的模式匹配4.7.18)POJ 2406 Power Strings(求一个字符串的最小重复串)
- POJ 3080 Blue Jeans(KMP模式匹配)
- [poj][3167][Cow Patterns]
- POJ-3167- Cow Patterns(KMP)