• POJ3461 Oulipo


    嘟嘟嘟

    今天又学了一遍kmp,总算是理解了。虽然这就是一道板子题,但我还想叨叨一会儿。

    kmp匹配的大致过程就是对于主串A,我们总想让A[i - j + 1 ~ i]和模式串B的最长前缀B[j]相等。匹配的时候如果A[i]和B[j + 1]不等,就把j = f[j],因为f[j]是保证了A[j - k + 1 ~ j]和B[k]相等的最大的k,那么可以得出对于A[i - 1],B和A[i - 1]的后缀相等的前缀中,最长的是j, 第二长的是f[j],第三长的是f[f[j]]……所以到了A[i],我们就从最长的开始试,如果B[j + 1] != A[i]的话,再试第二长的,看B[f[j] + 1]是否等于A[i],不行的话再看第三长的……所以说,我感觉kmp就是一种贪心……

    构造f数组和匹配几乎一样,这里说一点,就是f[1] = 0,然后我们从f[2]开始构造。为啥咧?因为一个串本身也是自己的前缀,如果从1开始,那么f[1] = 1,然后f[2]必定等于f[1] + 1,结果f数组就变成了f[1] = 1,f[2] = 2, f[3] = 3……很明显gg了。

     1 #include<cstdio>
     2 #include<iostream>
     3 #include<algorithm>
     4 #include<cmath>
     5 #include<cstring>
     6 #include<cstdlib>
     7 #include<cctype>
     8 #include<stack>
     9 #include<queue>
    10 #include<vector>
    11 using namespace std;
    12 #define enter puts("")
    13 #define space putchar(' ')
    14 #define Mem(a, x) memset(a, x, sizeof(a))
    15 #define rg register
    16 typedef long long ll;
    17 typedef double db;
    18 const int INF = 0x3f3f3f3f;
    19 const db eps = 1e-8;
    20 const int maxn = 1e4 + 5;
    21 inline ll read()
    22 {
    23   ll ans = 0;
    24   char ch = getchar(), las = ' ';
    25   while(!isdigit(ch)) las = ch, ch = getchar();
    26   while(isdigit(ch)) ans = ans * 10 + ch - '0', ch = getchar();
    27   if(las == '-') ans = -ans;
    28   return ans;
    29 }
    30 inline void write(ll x)
    31 {
    32   if(x < 0) putchar('-'), x = -x;
    33   if(x >= 10) write(x / 10);
    34   putchar(x % 10 + '0');
    35 }
    36 
    37 char s[maxn], t[maxn * 100];
    38 int f[maxn], cnt = 0;
    39 
    40 void init()
    41 {
    42   int m = strlen(s + 1);
    43   for(int i = 2, j = 0; i <= m; ++i)
    44     {
    45       while(j && s[j + 1] != s[i]) j = f[j];
    46       if(s[j + 1] == s[i]) j++;
    47       f[i] = j;
    48     }
    49 }
    50 void kmp()
    51 {
    52   cnt = 0;
    53   int m = strlen(s + 1), n = strlen(t + 1);
    54   for(int i = 1, j = 0; i <= n; ++i)
    55     {
    56       while(j && s[j + 1] != t[i]) j = f[j];
    57       if(s[j + 1] == t[i]) j++;
    58       if(j == m) cnt++, j = f[j];
    59     }
    60 }
    61 
    62 int main()
    63 {
    64   int T = read();
    65   while(T--)
    66     {
    67       scanf("%s
    %s", s + 1, t + 1);
    68       init();
    69       kmp();
    70       write(cnt); enter;
    71     }
    72   return 0;
    73 }
    View Code
  • 相关阅读:
    scrapy xpath 定位节点获取数据
    pandas 获取增量数据
    10秒解决80端口被占用
    VS code 自定义快捷键
    解决npm 的 shasum check failed for错误
    JSON.parse与eval的区别
    display:flex,用这个布局就像开挂了!!!
    几款前端IDE工具:Sublime、Atom、VSCode比较
    npm install -S -D -g 有什么区别
    Vue框架学习——使用nvm下载8.12.0以后版本没有npm文件的解决办法
  • 原文地址:https://www.cnblogs.com/mrclr/p/9764280.html
Copyright © 2020-2023  润新知