POJ 3167 Cow Patterns(模式串浮动匹配)

题目链接: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:

 1 #include <cstdio>
 2 #include <cstring>
 3 #include <vector>
 4 using namespace std;
 5 const int MAXN = 100005;
 6 const int MAXM = 25005;
 7 
 8 int a[MAXN];        // 存放主串
 9 int b[MAXM];        // 存放模式串
10 int as[MAXN][30];   // as[i][j] = k表示0 - i位中有k个数字j
11 int bs[MAXM][30];   // bs[i][j] = k表示0 - i位中有k个数字j
12 int next[MAXM];     // 存放模式串失配时的移动位数
13 vector<int> ans;    // 存放结果
14 int n, m, s;
15 
16 void Init()
17 {
18     ans.clear();
19     memset(as, 0, sizeof(as));
20     memset(bs, 0, sizeof(bs));
21     as[1][a[1]] = 1;
22     bs[1][b[1]] = 1;
23     for (int i = 2; i <= n; ++i)
24     {
25         memcpy(as[i], as[i - 1], sizeof(as[0]));
26         ++as[i][a[i]];
27     }
28     for (int i = 2; i <= m; ++i)
29     {
30         memcpy(bs[i], bs[i - 1], sizeof(bs[0]));
31         ++bs[i][b[i]];
32     }
33 }
34 
35 void GetNext()
36 {
37     memset(next, 0, sizeof(next));
38     int i = 1, j = 0, k = 0;
39     next[1] = 0;
40     while (i <= m)
41     {
42         int si = 0, sj = 0, ei = 0, ej = 0;
43         for (k = 1; k < b[i]; ++k)
44             si += bs[i][k] - bs[i - j][k];
45         ei = bs[i][k] - bs[i - j][k];
46         for (k = 1; k < b[j]; ++k)
47             sj += bs[j][k];
48         ej = bs[j][k];
49         if (0 == j || (si == sj && ei == ej)) next[++i] = ++j;
50         else j = next[j];
51     }
52 }
53 
54 void Kmp()
55 {
56     int i = 1, j = 1, k = 1;
57     while (i <= n)
58     {
59         int si = 0, sj = 0, ei = 0, ej = 0;
60         for (k = 1; k < a[i]; ++k)
61             si += as[i][k] - as[i - j][k];
62         ei = as[i][k] - as[i - j][k];
63         for (k = 1; k < b[j]; ++k)
64             sj += bs[j][k];
65         ej = bs[j][k];
66         if (0 == j || (si == sj && ei == ej)) ++i, ++j;
67         else j = next[j];
68         if (j == m + 1)
69         {
70             ans.push_back(i - m);
71             j = next[j];
72         }
73     }
74 }
75 
76 int main()
77 {
78     while (scanf("%d %d %d", &n, &m, &s) == 3)
79     {
80         for (int i = 1; i <= n; ++i) scanf("%d", &a[i]);
81         for (int i = 1; i <= m; ++i) scanf("%d", &b[i]);
82         Init();
83         GetNext();
84         Kmp();
85         size_t len = ans.size();
86         printf("%d
", len);
87         for (size_t i = 0; i < len; ++i) printf("%d
", ans[i]);
88     }
89     return 0;
90 }
原文地址:https://www.cnblogs.com/ykzou/p/4468786.html