【KMP】Ybt_重复子串

题目描述

给定若干个的字符串,询问每个字符串最多是由多少个相同的子字符串重复连接而成的。如:ababab 最多由 个 ab 连接而成。

输入

输入若干行,每行有一个字符串,字符串仅含英文字母。特别的,字符串可能为.即一个半角句号,此时输入结束。

输出

输出每个字符串最多是由多少个相同的子字符串重复连接而成。


处理Kmp值是肯定的。那么如何判断字符串是否符合条件呢?
我们略推一下数据:


ababab

a b a b a b
kmp 0 0 1 2 3 4

abcabc

a b c a b c
kmp 0 0 0 1 2 3

abadab

a b a d a b
kmp 0 0 1 0 1 2

abadab

a b a b c b
kmp 0 0 1 2 0 1

如此,我们可以发现:由重复子串构成的串的性质大概如下:

设一个循环节的长度为 k k k
则从 k + 1 k+1 k+1 位直到结束的 k m p kmp kmp 1 , 2 , 3... n − k − 1 , n − k 1,2,3...n-k-1,n-k 1,2,3...nk1,nk
易得 k = n − k m p [ n ] k = n-kmp[n] k=nkmp[n] ,循环节数为 n / k n/k n/k


代码

#include <cstdio>
#include <string>
#include <iostream>
using namespace std;
string a, b;
int j, n, kmp[1000010];
int main() {
    
    
    cin >> a;
    while (a != ".") {
    
    
        n = a.size();
        a = " " + a;  //便于处理
        kmp[0] = kmp[1] = j = 0;
        for (int i = 2; i <= n; ++i) {
    
    
            while (a[i] != a[j + 1] && j) j = kmp[j];
            if (a[i] == a[j + 1])
                ++j;
            kmp[i] = j;
        }
        if (n % (n - kmp[n]) == 0)
            printf("%d\n", n / (n - kmp[n]));
        else
            printf("1\n");
        cin >> a;
    }
}

猜你喜欢

转载自blog.csdn.net/qq_42937087/article/details/115407134
今日推荐