Java教程

KMP 算法的应用 -- 周期(求循环节)

本文主要是介绍KMP 算法的应用 -- 周期(求循环节),对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!

KMP 算法最基本的应用场景是字符串的模式匹配,然而其应用远不止于此,在匹配字符串的过程中用到的一部分思想本身在一些场景中也可以得到应用,比如下面的这道求循环节的题。

题目大意就是给出一个字符串,然后求它的某个长度的前缀是否由循环节组成,若有则输出这个前缀的长度和循环节个数。

附上题目链接:[POJ 1961 -- Period]http://poj.org/problem?id=1961

本题只需要用到 next 数组。

对于一个字符串,我们构建了 next 数组之后,对于一个长度为 n 的前缀,如果它由循环节构成,那么它的 next 数组和它的长度之间有什么关系?

如果这个前缀由循环节构成,那么它的循环节一定是 s[1~n-m],因此只要看这个前缀的长度是否是 n-m 的倍数(大于1)。

AC 代码

#include <iostream>

using namespace std;

const int N = 1e6+10;

char p[N];

int n,ne[N],cnt;

int main(){
    while(cin>>n,n){
        cin>>(p+1);
        
        for(int i = 2,j = 0; i <= n ; i ++){
            while(j && p[j+1] != p[i]) j = ne[j];
            if(p[j+1] == p[i]) j++;
            ne[i] = j;
        }
        cout<<"Test case #"<<++cnt<<endl;
        for(int i = 2;i <= n ; i ++){
            int k = i - ne[i];
            if(i%k == 0 && i/k > 1)printf("%d %d\n",i,i/k);
        }
        puts("");
    }
    
    return 0;
}

同时附上一篇比较详细的讲解 kmp 的文章,以便日后复习。
https://www.cnblogs.com/yjiyjige/p/3263858.html

这篇关于KMP 算法的应用 -- 周期(求循环节)的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!