KMP算法

对于匹配一个字符串是否为另外一个字符串的子串,传统的算法是先从头比较,当遇到不等时在回溯过去,从第二个字母开始匹配,kmp算法就是能够消除回溯,提升效率。PS:KMP为三老外的名字缩写。web

KMP算法大意:设s为目标串(主串),t为模式串,并设i指针和j指针分别指示目标串和模式串中正待比较的字符,令i和j的初值都为零。如有si=tj,则i和j分别加1;不然,i不变,j退回到j=next[j]的位置(即模式串右滑),比较si和tj,若相等则指针各加1,不然j再退回到下一个j=next[j]位置(即模式串继续右滑),再比较si和tj。以此类推,直到出现下列两种状况之一:一种是j退回到某个j=next[j]位置时有si=tj,则指针各加1后继续匹配;另外一种是j退回到j=-1时,此时令i,j指针各加1,即下一次比较s(i+1)和t0。算法

next[j]数组:此数组主要针对模式串,next[j]表示的是在模式串中第j个字符前面最大的前缀与后缀相等(并不是是对称)的长度,如“abcac”中,next[0]=-1(第一个为方便代码通常都设为-1),next[1]=next[2]=next[3] =0,next[4]=1(由于有a=a)。PS:重点数组

例题:spa

    

Period指针

Time Limit: 3000MS Memory Limit: 30000K
Total Submissions: 13155 Accepted: 6167

Descriptioncode

For each prefix of a given string S with N characters (each character has an ASCII code between 97 and 126, inclusive), we want to know whether the prefix is a periodic string. That is, for each i (2 <= i <= N) we want to know the largest K > 1 (if there is one) such that the prefix of S with length i can be written as AK ,that is A concatenated K times, for some string A. Of course, we also want to know the period K.orm

Inputip

The input consists of several test cases. Each test case consists of two lines. The first one contains N (2 <= N <= 1 000 000) – the size of the string S.The second line contains the string S. The input file ends with a line, having the
number zero on it.字符串

Outputget

For each test case, output "Test case #" and the consecutive test case number on a single line; then, for each prefix with length i that has a period K > 1, output the prefix size i a

Sample Input

3 nd the period K separated by a single space; the prefix sizes must be in increasing order. Print a blank line after each test case.

aaa 12 aabaabaabaab 0

Sample Output

Test case #1 2 2 3 3 Test case #2 2 2 6 2 9 3 12 4

题目大意:给你若干个字符串,判断该字符串的前n位最多重复了几回,好比,给ababab,结果是前4位重复了2次,前6位重复了3次。

CODE:

#include<stdio.h>#include<string.h>#define maxlen 1000001char str[maxlen];int  next[maxlen];void get_next()//求next数组{    int j=0,k=-1,l=strlen(str);    next[0]=-1;    while(j<l)    {        if(k==-1||str[j]==str[k])        {            j++;            k++;            next[j]=k;        }        else            k=next[k];    }    return;}int main(){    int n,len,i,test=0;    while(scanf("%d",&n)&&n)    {        getchar();        gets(str);        get_next();        printf("Test case #%d\n",++test);        for(i=2; i<=n; i++) //求出前i个字符中重复串        {            len=i-next[i];            if(i%len==0&&i/len>1)                printf("%d %d\n",i,i/len);        }        printf("\n");    }    return 0;}KMP算法复杂度为O(m+n),普通法为O(m*n)。

相关文章
相关标签/搜索