kmp算法及改进

来源:互联网 发布:u9数据字典怎么用 编辑:程序博客网 时间:2024/06/06 00:55
一、failture版int pmatch(char *string,char *pat){    int i=0,j=0;    int lens=strlen(string);//主字符串    int lenp=strlen(pat);//需要匹配的字符串    while(i < lens && j < lenp)    {        if(string[i]==pat[j])//如果顺利匹配,下标都移动        {            i++;            j++;        }        else if(j==0)//如果需要匹配的字符串首字母都不匹配,主串移动下标            i++;        else //都不是的情况            j=failure[j-1]+1;    }    return ((j==lenp) ? (i-lenp):-1);//返回的是主串匹配的首元素下标}void fail(char *pat){    int n=strlen(pat);    failure[0]=-1;    int i,j;    for( j=1;j<n;j++)    {        i=failure[j-1];        while((pat[j]!=pat[i+1]) && (i >= 0))//检测需要匹配的串是否有重复的部分            i = failure[i];        if(pat[j] == pat[i+1])//如果有重复,记住位置,当匹配出错,就将需要匹配字符串的下标移动到前面重复出现的字母的下标(下面的例子)            failure[j] = i+1;        else             failure[j] = -1;    }}            a  b  c  a  b  c  a  c  a  bfailture    -1 -1 -1 0  1  2  3  -1 0  1二、nextval版(kmp改进)#include<stdio.h>#include<string.h>void get_nextval(char *T,int *nextval){    int i,j;    i=1;    j=0;    nextval[0]=0;    while(i<strlen(T))    {        if(j==0|| T[i]==T[j])        {            if(T[i]!=T[j])//和未改进算法一样                nextval[i]=j;            else                 nextval[i]=nextval[j];//改进就是把之前出现过的都表示一个地方            ++i;            ++j;        }        else             j=nextval[j];    }}int Index_KMP(char *S,char *T,int pos){    int i=pos;//可以实现任意开始位置匹配    int j=0;    int len1=strlen(S);    int len2=strlen(T);    int next[255]={0};    get_nextval(T,next);    while(i<len1&&j<len2)    {        if(j==0||S[i]==T[j])        {            ++i;            ++j;        }        else             j=next[j];    }    if(j>=len2)        return i-len2;    else         return -1;}int main(){    char *a="aaabbaaabbb";    char *b="aaabbb";    printf("%d\n",Index_KMP(a,b,0));//从头开始匹配    return 0;}
原创粉丝点击