zoukankan      html  css  js  c++  java
  • 数据结构 02KMP

    KMP模板:

    求next数组

    //求next数组
    for (int i = 2, j = 0; i <= n; i ++ )
    {
        while (j && p[j] != p[j + 1]) j = ne[j];
        if (p[i] == p[j + 1]) j ++;
        ne[i] = j;
    }

    处理母串

    for (int i = 1, j = 0; i <= m; i ++ )
    {
        while (j && s[i] != p[j + 1]) j = ne[j];
        if (s[i] == s[j + 1]) j ++;
        if (j == n)
        {
            
        }
        
        f[i] == j;
    //    if (f[i] == n)此时p在s串中第一次出现
    }

    KMP最小循环节、循环周期

    假设S长度位len,则s存在最小循环节,循环节的长度L为len-ne[len], 子串为s[1, len - ne[n]]

    (1)如果len可以被len-ne[len]整除,则表明字符串s完全由循环节循环组成,循环周期为T = len / L

    (2)如果不能,说明还需要再添加几个字母才能补全。需要补的个数是循环个数L - len % L = L - (len - L) % L = L - ne[len] % L,

    其中L = len - ne[len]

     

    Power Strings

    Description
    
    Given two strings a and b we define a*b to be their concatenation. For example, if a = "abc" and b = "def" then a*b = "abcdef". If we think of concatenation as multiplication, exponentiation by a non-negative integer is defined in the normal way: a^0 = "" (the empty string) and a^(n+1) = a*(a^n).
    Input
    
    Each test case is a line of input representing s, a string of printable characters. The length of s will be at least 1 and will not exceed 1 million characters. A line containing a period follows the last test case.
    Output
    
    For each s you should print the largest n such that s = a^n for some string a.
    Sample Input
    
    abcd
    aaaa
    ababab
    .
    Sample Output
    
    1
    4
    3
    Hint
    
    This problem has huge input, use scanf instead of cin to avoid time limit exceed.
    Source
    

     代码:

    #include <cstdio>
    #include <cstring>
    #include <iostream>
    #include <algorithm>
    
    using namespace std;
    
    const int N = 1000010;
    
    int len;
    char s[N];
    int ne[N];
    
    void work()
    {
      len = strlen(s + 1);
    
      for (int i = 2, j = 0; i <= len; i ++ )
      {
        while (j && s[i] != s[j + 1]) j = ne[j];
        if (s[i] == s[j + 1]) j ++;
        ne[i] = j;
      }
    
      int t = len - ne[len];
      if (len % t == 0) printf("%d
    ", len / t);
      else puts("1");
    }
    int main()
    {
      while (scanf("%s", s + 1))
      {
        if (s[1] == '.') return 0;
        memset(ne, 0, sizeof ne);
        work();
      }
    }
    

      

     

     

     

     

     

     

     

     

     

     

     

  • 相关阅读:
    {purple8}
    {purple7}
    {暴力}
    uva1103(dfs)
    {purple5练习题}
    c++复习题
    关于继承
    lrj紫书第五章
    20个Linux系统监视工具
    linux上配置jdk+Apache
  • 原文地址:https://www.cnblogs.com/Iamcookieandyou/p/14806536.html
Copyright © 2011-2022 走看看