KMP算法类习题——字符串匹配

Description

For each prefix with length P of a given string S,if

S[i]=S[i+P] for i in [0..SIZE(S)-p-1],

then the prefix is a “period” of S. We want to all the periodic prefixs.

Input

Input contains multiple cases.

The first line contains an integer T representing the number of cases. Then following T cases.

Each test case contains a string S (1 <= SIZE(S) <= 1000000),represents the title.S consists of lowercase ,uppercase letter.

Output

For each test case, first output one line containing "Case #x: y", where x is the case number (starting from 1) and y is the number of periodic prefixs.Then output the lengths of the periodic prefixs in ascending order.

Sample Input

4
ooo
acmacmacmacmacma
fzufzufzuf
stostootssto

Sample Output

Case #1: 3
1 2 3
Case #2: 6
3 6 9 12 15 16
Case #3: 4
3 6 9 10
Case #4: 2
9 12


参考代码:

#include <cstdio>

#include <cstring>

const int maxn = 1000010;

int p[maxn],ans[maxn];

char str[maxn]; //保存字符串的数组

 

void get_p(int len){

    p[1] = 0;

    int j = 0;

    for(int i = 2;i <= len;i++){

        while(j > 0 && str[j+1] != str[i])  j = p[j];

//这个循环是当结果失配时才使用的

        if(str[j+1] == str[i])  j++;

        p[i] = j;

    }

}

 

int main(){

    int nkase;

    scanf("%d",&nkase);

    for(int kase = 1;kase <= nkase;kase++){

        scanf("%s",str+1);

// 这个+1表示的含义是从下标为1的地方开始输入,方便后续的操作

//C中这样控制字符串输入的格式还是非常方便的 

        int len = strlen(str+1);

        get_p(len);  

//这个是单单初始化了数组p得到了结果,然后主要的思想未知,可能是在求解next数组

//str的长度告诉函数,通过匹配的方式得到数组p,相当于next数组

        int t = p[len],cnt = 0;

        while(t){

            ans[cnt++] = len-t;

            t = p[t];

//每次取到的数值是一定会比以前的要小,所以这不可能是一个死循环的

        }

        ans[cnt++] = len;

//在这里将所有的运算结果全部保留下来,包括数量cnt和最后输出的结果ans[];

        printf("Case #%d: %d ",kase,cnt);

//在这里有两个参数,即运行的次数和返回的结果数

        for(int i = 0;i < cnt-1;i++)  printf("%d ",ans[i]);

       printf("%d ",ans[cnt-1]);

 

    }

    return 0;

}

关键点分析:

本题还是要先找到next数组,然后通过next数组来访问求解。

当然,每个next数组保存的内容都是不一样的,都是前一个字符匹配得到的信息结果保留在那个地方。

//KMP的算法重点就是求解next数组,当求解next数组时要知道关键点就是next数组中保存的数据是什么意思,那是当失配的时候后缀部分和前面的部分是否相同的表现

我要坚持一年,一年后的成功才是我想要的。
原文地址:https://www.cnblogs.com/tianxia2s/p/3872928.html