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\n", len);

87         for (size_t i = 0; i < len; ++i) printf("%d\n", ans[i]);

88     }

89     return 0;

90 }

 

你可能感兴趣的:(Pattern)