数据结构 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\n", len / t);
  else puts("1");
}
int main()
{
  while (scanf("%s", s + 1))
  {
    if (s[1] == '.') return 0;
    memset(ne, 0, sizeof ne);
    work();
  }
}

  

 

 

 

 

 

 

 

 

 

 

 

posted @ 2021-05-24 22:30  rookie161  阅读(79)  评论(0编辑  收藏  举报