• POJ 2406 Power Strings (KMP)


    Power Strings

    Time Limit: 3000MS
    Memory Limit: 65536K

    Total Submissions: 29663
    Accepted: 12387

    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
     
    ::初学KMP真心不容易,理解起来很吃力,还好今天老师有讲解KMP的基本原理,现在思路清晰了一点,赶紧做这道以前暴力过的题。
    证明:(PKU 2406 POWER STRINGS --- 字符串匹配,KMP算法

    定理:假设S的长度为len,则S存在循环子串,当且仅当,len可以被len - next[len]整除,最短循环子串为S[len - next[len]]
    例子证明:

    设S=q1q2q3q4q5q6q7q8,并设next[8] = 6,此时str = S[len - next[len]] = q1q2,由字符串特征向量next的定义可知,q1q2q3q4q5q6 = q3q4q5q6q7q8,即有q1q2=q3q4,q3q4=q5q6,q5q6=q7q8,即q1q2为循环子串,且易知为最短循环子串。由以上过程可知,若len可以被len - next[len]整除,则S存在循环子串,否则不存在。
    解法:利用KMP算法,求字符串的特征向量next,若len可以被len - next[len]整除,则最大循环次数n为len/(len - next[len]),否则为1。

       1: #include <cstdio>
       2: #include <cstring>
       3: #include <algorithm>
       4: using namespace std;
       5: const int maxn=1e6;
       6: char s[maxn+10];
       7: int next[maxn+10];
       8:  
       9: void get_next(char s[],int len)
      10: {
      11:     int i=0,j=-1;
      12:     next[0]=-1;
      13:     while(i<len)
      14:     {
      15:         if(j==-1||s[i]==s[j]) {j++; i++; next[i]=j;}
      16:         else j=next[j];
      17:     }
      18: }
      19:  
      20: int main()
      21: {
      22:     while(scanf("%s",s),s[0]!='.')
      23:     {
      24:         int len=strlen(s);
      25:         get_next(s,len);
      26:         if(len%(len-next[len])==0)
      27:             printf("%d
    ",len/(len-next[len]));
      28:         else
      29:             printf("1
    ");
      30:     }
      31:     return 0;
      32: }
  • 相关阅读:
    前中后序建立树或者直接历遍
    Leetcode:面试题 04.03. 特定深度节点链表
    按层数层序历遍
    Solidity函数修饰符
    无线传感网定位技术
    无线传感器网络概述,传感器网络结构
    Solidity高级用法
    智能合约交互
    内存
    CPU的态
  • 原文地址:https://www.cnblogs.com/zyx1314/p/3615651.html
Copyright © 2020-2023  润新知