zoukankan      html  css  js  c++  java
  • HDU 3746(KMP)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1358

    题意:给你一个字符串,要求将字符串的全部字符最少循环2次需要添加的字符数。 例子: abcabc 已经循环2次,添加数为0 abcac 没有循环2次,添加字符abcac。数目为5. abcabcab 已

    经循环过2次,但第三次不完整,需要添加数为1 分析:还是用到了next数组,这个循环节这很巧妙啊。。。 做这个题需要好好理解KMP算法,尤其是next数组。

    非优化的next数组的含义是:next[i]=k默示模式串下标为i的字符的前k-1个字符与开首的前k-1个字符相等,那么从1到i-1的模式串必定是轮回的,且循环节的长度为i-next[i].

    理解了这一点这个题就很简单了。

    总之 next含义是:

    next[j]表代表j之前的字符串的真前缀和真后缀最大匹配长度 next[i]代表了前缀和后缀的最大匹配的值(需要彻底明白这点http://www.shengxun8.com/,相当重要)

    非优化的next数组的含义是:next[i]=k默示模式串下标为i的字符的前k-1个字符与开首的前k-1个字符相等

    代码如下:

     1 #include <cstdio>
     2 #include <cstring>
     3 using namespace std;
     4 
     5 const int N = 100002;
     6 char str[N];
     7 int  next[N];
     8 
     9 void get_next(int len)
    10 {
    11         int i = 0;
    12         int j = -1;
    13         next[i] = -1;
    14         while(i < len)
    15         {
    16             if(j == -1 || str[i] == str[j])
    17             {
    18                 i++;
    19                 j++;
    20                 next[i] = j;
    21             }
    22             else
    23             {
    24                 j = next[j];
    25             }
    26         }
    27 }
    28 
    29 int main()
    30 {
    31     int t;
    32     scanf("%d", &t);
    33     while(t--)
    34     {
    35         scanf("%s", str);
    36         int len = strlen(str);
    37         get_next(len);
    38         int x = len - next[len];
    39         if(len != x && (len % x == 0))
    40         {
    41             printf("0\n");
    42         }
    43         else
    44         {
    45             printf("%d\n", x - next[len] % x);
    46         }
    47     }
    48     return 0;
    49 }

    参考别人的代码:

     1 #include <cstdio>
     2 #include <cstring>
     3 using namespace std;
     4 
     5 const int N = 100002;
     6 char str[N];
     7 int next[N];
     8 
     9 void get_next(int len)
    10 {
    11     int i;
    12     int j = 0;
    13     for(next[1] = 0, i = 2; i <= len; i++)
    14     {
    15         while(j && str[j + 1] != str[i])
    16         {
    17             j = next[j];
    18         }
    19         if(str[j + 1] == str[i])
    20         {
    21             j++;
    22         }
    23         next[i] = j;
    24     }
    25 }
    26 
    27 int main()
    28 {
    29     int t;
    30     scanf("%d", &t);
    31     while(t--)
    32     {
    33         scanf("%s", str + 1);
    34         int len = strlen(str + 1);
    35         get_next(len);
    36         int x = len - next[len];
    37         if(len % x == 0 && len != x)
    38         {
    39             printf("0\n");
    40         }
    41         else
    42         {
    43             printf("%d\n", x - next[len] % x);
    44         }
    45     }
    46 }

    主要是next数组的求法不同,第一种是经过优化的,而第二种未经过优化。

  • 相关阅读:
    39门课程。加油!学长只能帮你到这里了!
    联邦企业架构之CIO委员会的企业架构实施指南(上)
    RTEMS 进程切换分析
    styleCop使用介绍和Fxcop使用参考
    获得Web目录URL
    HelloWorld demo
    第一个C语言程序
    文件分布式存储方案
    Linux常用指令别名、输入/输出重定向、管道、命令连接符、命令替换符
    JavaEE项目问题总结
  • 原文地址:https://www.cnblogs.com/10jschen/p/2648843.html
Copyright © 2011-2022 走看看