zoukankan      html  css  js  c++  java
  • poj1961 Period

    我们考虑KMP算法中fail失配指针的意义。

    对于一个模式串(Pattern),位置i对应的失配指针fail[i]是那个位置:

    这个位置满足的条件是,子串[0, fail[i])是位置i(不含)的后缀,并且fail[i]是所有满足此条件的位置中最靠后(最接近i)的那个。

    也就说当我们用模式串P匹配文本串T的时候,我们检查当前位置T[i]与P[j]是否匹配,

    若匹配i,j指针各向前移动一位;

    否则,利用模式子串[0, j)与文本子串i(不含)的后缀已经匹配的信息,保持i指针不变,j指针退到fail[j]位置再次尝试匹配。

    退回的指针位置同样应该满足P的前缀与i(不含)后缀相匹配。

    那么一个模式串fail指针蕴含着当前位置后缀与模式串前缀匹配的信息。

    回到本题,考虑位置i(>0),若i位置是某个重复节(长度设为len)的终点,那么其失配指针必然指向(i - len)位置,

    并且满足len | (i + 1) && str[i - len] == str[i]。

    反之我们有满足此条件的必然是某个重复节的终点:

    因为[0, fail[i]]可用字符串拼接表示:s1 + s2 + ... + sk + t,其中strlen(si) = len,

    那么[len, i]必然是s2 +... + sk + t + t。

    有s1 = s2 && s2 == s3 &&... && sk -1 = sk && sk = t。

    可见该条件对于所求是等价的。

    http://poj.org/problem?id=1961

     1 #include <cstdio>
     2 #include <cstring>
     3 #include <algorithm>
     4 using namespace std;
     5 const int maxn = 1e6 + 10;
     6 char str[maxn];
     7 int n;
     8 int fail[maxn];
     9 
    10 int main(){
    11     //freopen("in.txt", "r", stdin);
    12     int kase = 0;
    13     while(~scanf("%d", &n) && n){
    14         char ch, *p = str;
    15         while((ch = getchar()) != '
    ') ch = getchar();
    16         for(int i = 0; i < n; i++) *(p++) = getchar();
    17         fail[0] = fail[1] = 0;
    18         for(int i = 1; i < n; i++){
    19             //compute forward not backward
    20             int j = fail[i];
    21             while(j && str[j] != str[i]) j = fail[j];
    22             fail[i + 1] = str[j] == str[i] ? j + 1 : 0;
    23         }
    24         printf("Test case #%d
    ", ++kase);
    25         for(int i = 1; i < n; i++){
    26             int delta = i - fail[i];
    27             if((i + 1) % delta == 0 && str[i] == str[fail[i]]){
    28                 printf("%d %d
    ", i + 1, (i + 1) / delta);
    29             }
    30         }
    31         putchar('
    ');
    32     }
    33 }
    View Code
  • 相关阅读:
    SpringCloud系列——SSO 单点登录
    SpringBoot系列——Redis
    基于“formData批量上传的多种实现” 的多图片预览、上传的多种实现
    SpringCloud系列——Bus 消息总线
    SpringCloud系列——Config 配置中心
    SpringCloud系列——Zuul 动态路由
    SpringCloud系列——Ribbon 负载均衡
    SpringCloud系列——Feign 服务调用
    SpringCloud系列——Eureka 服务注册与发现
    ZXing 生成、读取二维码(带logo)
  • 原文地址:https://www.cnblogs.com/astoninfer/p/4867535.html
Copyright © 2011-2022 走看看