• poj 2752 Seek the Name, Seek the Fame


    还是KMP,我觉得应该把自己的心得写一下。这题要求的是“前后辍”,即既是前辍又是后辍,比如“abcab”中的“ab”。KMP求next数组有两种算法,一种是:

    if(t[i] == t[j])

    { i++; j++; next[i] = j; }

    另一种是:

    if(t[i] == t[j])

    { i++; j++;

      if(t[i] != t[j])

        next[i] = j;

      else

        next[i] = next[j];

    }

    第二种是第一种的改进版,不过这一题恰恰是第一种比较合适。对字串“ababcabab”来说,两种方法构造的next分另为:

    a b a b c a b a b  
    -1 0 -1 0 2 -1 0 -1 0 4
    -1 0 0 1 2 0 1 2 3

    4

    在文中插表格太麻烦,我就做成这样了。上一行是第二种,下一行是第一种方法,从左到右分别为next[0]到next[10],第一种方法的数组满足这样的性质:对任意 i ,next[i] = j 表示字串中前 i 个字符组成的子串的最长“前后辍”长度为 j 。比如,‘c’ 对应着next[4] = 2,那么前4个字符“abab” 的最长前后辍“ab”的长度为2。这样就好办多了,“ababcabab” 的最长串为“abab”,“abab”的最长串为“ab”,递归打印就行了。

     1 #include <stdio.h>
     2 #include <string.h>
     3 int next[1000005],len;
     4 char T[1000005];
     5 void getnext(char *t)
     6 {
     7     int i=0,j=-1;
     8     len = strlen(T);
     9     next[0] = -1;
    10     while(i < len)
    11         if(j == -1 || T[i]==T[j])
    12         {
    13             i++;j++;
    14             next[i] = j;
    15         }
    16         else j = next[j];
    17 }
    18 void show(int a)
    19 {
    20     if(next[a])
    21         show(next[a]),
    22         printf(" %d",a);
    23     else printf("%d",a);
    24 }
    25 int main()
    26 {
    27     while(~scanf("%s",T))
    28     {
    29         getnext(T);
    30         show(len);
    31         printf("\n");
    32     }
    33     return 0;
    34 }

    PS:刚刚才发现,第二种数组虽不对任意 i 满足上述性质,但是在这一题相应的位置上是满足的,晕死,那不就是两种都可以了。

  • 相关阅读:
    mongodb的常用操作(二)
    mongodb的常用操作
    OpenBSD内核之引导PBR
    OpenBSD内核之引导MBR
    OpenBSD之开篇
    “索引”、大数据的思考
    flume坑之channel.transactionCapacity和HdfsSink.batchSize
    cocos2d-x的CCAffineTransform相关变换实现原理
    MySQL JDBC/MyBatis Stream方式读取SELECT超大结果集
    “全服单世界”的终极目标即“虚拟世界”
  • 原文地址:https://www.cnblogs.com/lzxskjo/p/2484670.html
Copyright © 2020-2023  润新知