KMP的朴素算法与改进

来源:互联网 发布:我想学软件开发 编辑:程序博客网 时间:2024/06/05 12:28

KMPs算法:KMP算法是一种改进的字符串匹配算法,由D.E.Knuth,J.H.Morris和V.R.Pratt同时发现,因此人们称它为克努特——莫里斯——普拉特操作(简称KMP算法)。KMP算法的关键是利用匹配失败后的信息,尽量减少模式串与主串的匹配次数以达到快速匹配的目的。具体实现就是实现一个next()函数,函数本身包含了模式串的局部匹配信息。时间复杂度O(m+n)。

代码:

/************************Author: herongweiDate  : 2017/2/25 13:42 ************************/#include <iostream>#include <stdio.h>#include <stdlib.h>#include <string.h>#include <algorithm>using namespace std;const int maxn = 1e5+10;char S[maxn],T[maxn];int T_len,S_len;int next[maxn],nextval[maxn];/*KMP 朴素模式匹配算法【时间复杂度】 O(n+m)*//*返回字串T的next数组get_next */void get_next(char T[],int next[]){    int i,j;    i=1;    j=0;    next[1]=0;    while(i<T_len)    {        if( j==0 || T[i]==T[j]) /// T[i]表示后缀T[j]表示前缀        {            ++i;++j;            next[i]=j;        }        else {            j=next[j];         ///若字符不同,则J回溯        }    }}/*返回字串T在主串S中第POS个字符之后的位置。若不存在,则函数返回值0*/int index_kmp(char T[],char S[],int pos){    int i=pos; /*i用于主串S当前位置下标值,若pos 不是1 则从pos 位置开始匹配*/    int j=1;   /*子串T当前位置下标值*/    //int nextt[maxn];    get_next(T,next); /*对T分析,得到next数组*/    while(i<=S_len && j<=T_len)    {        if(j==0 || S[i] ==T[j])        {            ++i;++j;        }        else        {            j=next[j];           ///若字符不同,则J回溯        }    }    if(j>T_len) return i-T_len;    else return 0;}/*KMP 模式匹配算法改进【时间复杂度】 O(n+m)【一句话总结改进】:它是在计算出next值的同时,如果a位字符与它next值指向的b位字符相等, 则该a位的nextval就指向b位的nextval的值,如果不等,则该a位的nextval值就是它自己a位的next值。*/void get_nextval(char T[],int nextval[]){    int i,j;    i=1;    j=0;    nextval[1]=0;    while(i<T_len)    {     if(j==0 || T[i]==T[j])/// T[i]表示后缀T[j]表示前缀     {         ++i;++j;        if(T[i]!=T[j]) nextval[i]=j; ///若当前字符与前缀字符不匹配                                     ///则当前的J为nextval 在i 位置的值        else nextval[i]=nextval[j];  ///若当前与前缀相同,则将前缀字符的nextval的值                                     ///赋给nextval在i位置的值     }     else j=nextval[j];              ///若字符不同,则J回溯    }}int main(){    T_len=strlen(T);S_len=strlen(S);    //input    return 0;}
1 0
原创粉丝点击