字符串KMP小结

来源:互联网 发布:网络电视盒能收多少台 编辑:程序博客网 时间:2024/06/05 05:05

一:返回模式串在主串的下标BF与KMP与KMP1

#include <iostream>#include<malloc.h>#include<cstdio>using namespace std;#define MaxSize 100int next[MaxSize];int nextval[MaxSize];typedef struct{    char data[MaxSize];    int length;} SqString;void Assign(SqString &s,char cstr[]){    int i;    for(i=0; cstr[i]!='\0'; i++)        s.data[i]=cstr[i];    s.length=i;}int BF(SqString s,SqString t){    int i=0,j=0;    while(i<s.length&&j<t.length)    {        if(s.data[i]==t.data[j])        {            i++;            j++;        }        else        {            i=i-j+1;            j=0;        }    }    if(j>=t.length)            return i-t.length;        else            return -1;}void GetNext(SqString t,int next[]){    int i=0,j=-1;    next[0]=-1;    while(i<t.length-1)    {        if(j==-1||t.data[i]==t.data[j])        {            i++;            j++;            next[i]=j;        }        else            j=next[j];    }}int KMP(SqString s,SqString t){    int i=0,j=0;    GetNext(t,next);    while(i<s.length&&j<t.length)    {        if(j==-1||s.data[i]==t.data[j])        {            i++;            j++;        }        else            j=next[j];    }    if(j>=t.length)        return i-t.length;    else        return -1;}void GetNextVal(SqString t,int next[]){    int i=0,j=-1;    nextval[0]=-1;    while(i<t.length)    {        if(j==-1||t.data[i]==t.data[j])        {            i++;            j++;            if(t.data[i]!=t.data[j])                nextval[i]=j;            else                nextval[i]=nextval[j];        }        else            j=nextval[j];    }}int KMP1(SqString s,SqString t){    int i=0,j=0;    GetNextVal(t,next);    while(i<s.length&&j<t.length)    {        if(j==-1||s.data[i]==t.data[j])        {            i++;            j++;        }        else            j=nextval[j];    }    if(j>=t.length)        return i-t.length;    else        return -1;}int main(){    SqString s,t;    Assign(s,"abcdefghi");    Assign(t,"cdef");    printf("用BF算法返回匹配下标:");    printf("%d\n",BF(s,t));    printf("用KMP算法返回匹配下标:");    printf("%d\n",KMP(s,t));    printf("用修正后的KMP算法返回匹配下标:");    printf("%d\n",KMP1(s,t));    return 0;}

二:返回模式串在主串中出现的次数

如图:

#include <iostream>#include<malloc.h>#include<cstdio>using namespace std;#define MaxSize 100int next[MaxSize];int nextval[MaxSize];int n;typedef struct{    char data[MaxSize];    int length;} SqString;void Assign(SqString &s,char cstr[]){    int i;    for(i=0; cstr[i]!='\0'; i++)        s.data[i]=cstr[i];    s.length=i;}int BF(SqString s,SqString t){    int i=0,j=0,n=0;    while(i<s.length&&j<t.length)    {        if(s.data[i]==t.data[j])        {            i++;            j++;        }        else        {            i=i-j+1;            j=0;        }        ///仅仅在此部分做了处理                if(j>=t.length)        {            n++;            i=i-j+1;            j=0;        }    }    return n;}void GetNext(SqString t,int next[]){    int i=0,j=-1;    next[0]=-1;    while(i<t.length-1)    {        if(j==-1||t.data[i]==t.data[j])        {            i++;            j++;            next[i]=j;        }        else            j=next[j];    }}int KMP(SqString s,SqString t){    int i=0,j=0,n=0;    GetNext(t,next);    while(i<s.length&&j<t.length)    {        if(j==-1||s.data[i]==t.data[j])        {            i++;            j++;        }        else            j=next[j];        ///仅仅在此部分做了处理        if(j>=t.length)        {            n++;            i=i-j+1;            j=0;        }    }    return n;}void GetNextVal(SqString t,int next[]){    int i=0,j=-1;    nextval[0]=-1;    while(i<t.length)    {        if(j==-1||t.data[i]==t.data[j])        {            i++;            j++;            if(t.data[i]!=t.data[j])                nextval[i]=j;            else                nextval[i]=nextval[j];        }        else            j=nextval[j];    }}int KMP1(SqString s,SqString t){    int i=0,j=0,n=0;    GetNextVal(t,next);    while(i<s.length&&j<t.length)    {        if(j==-1||s.data[i]==t.data[j])        {            i++;            j++;        }        else            j=nextval[j];        ///仅仅在此部分做了处理        if(j>=t.length)        {            n++;            i=i-j+1;            j=0;        }    }    return n;}int main(){    SqString s,t;    Assign(s,"abcdefghicdefcdef");    Assign(t,"cdef");    printf("用BF算法返回匹配次数:");    printf("%d\n",BF(s,t));    printf("用KMP算法返回匹配次数:");    printf("%d\n",KMP(s,t));    printf("用修正后的KMP算法返回匹配次数:");    printf("%d\n",KMP1(s,t));    return 0;}

三:最小循环节,即最大的循环次数

如图:POJ2406

len-next[len]是最小循环节,而len/(len-next[len])是最大的循环次数


#include <iostream>#include<string.h>#include<cstdio>using namespace std;char t[1000000];int next[1000000];void getnext(){    int i=0,j=-1;    next[0]=-1;    while(i<strlen(t))    {        if(j==-1||t[i]==t[j])        {            i++;            j++;            next[i]=j;        }        else            j=next[j];    }}int main(){    while(scanf("%s",t))    {        if(t[0]=='.')            break;        int len=strlen(t);        getnext();        if(len%(len-next[len])==0)            printf("%d\n",len/(len-next[len]));        else            printf("1\n");    }    return 0;}

字符串的所有大小循环节以及他们的周期POJ1961

如图:

///i-next[i]是循环节的长度

void getnext(const char *t)///有无参数都行

#include <iostream>#include<string.h>#include<cstdio>using namespace std;char t[1000000];int next[1000000];int len;void getnext(const char *t)///无参数也行{    int i=0,j=-1;    next[0]=-1;    while(i<strlen(t))    {        if(j==-1||t[i]==t[j])        {            i++;            j++;            next[i]=j;        }        else            j=next[j];    }}int main(){    int ant=0;    while(scanf("%d",&len)&&len)    {        scanf("%s",t);        getnext(t);///无参数也行        printf("Test case #%d\n",++ant);        for(int i=1;i<=len;i++)        {            if(i%(i-next[i])==0&&(i!=i-next[i])) ///如果有多个循环节            printf("%d %d\n",i,i/(i-next[i]));        }        printf("\n");    }    return 0;}

哈哈




0 0
原创粉丝点击