KMP的简单实现

来源:互联网 发布:怎么克服懒惰 知乎 编辑:程序博客网 时间:2024/06/06 00:57

kmp算法是一种效率非常高的字符串匹配算法。
给定两个字符串str和ptr,长度分别为n和m,判断str是否在ptr中出现,如果出现则返回出现的位置。
kmp算法实现方式

我先举个例子:
str:abcabcabe
ptr:abcabe
首先将abcabe转化为next数组000120
这是怎么转化的呢,
第一位表示a 它的最长 的 相同的前缀和后缀的长度为 0
第二位表示ab 它的最长 的 相同的前缀和后缀的长度为 0
第三位表示abc 它的最长的 相同的前缀和后缀的长度为 0
第四位表示abca 它的最长的相同的前缀和后缀的长度为1(前缀a 后缀a)
第五位表示 abcab 它的最长的相同的前缀和后缀的长度为2(前缀 ab 后缀ab)
第六位表示abcabe 它的最长的相同的前缀和后缀的长度为0
注意:前缀表示第一位到倒二位。

将ptr转化为next数组后,我就开始比较。

str[0]==ptr[0],
接着str[1]==ptr[1]继续比较直到str[5]!=ptr[5],这时将str[5]和ptr[next[5-1]]进行比较。为什么这样呢?
str:abcabcabe
ptr:abcabe
000120
当c不等于e时,e前表示已经匹配成功,next[5-1]表示e前的元素 相同的前缀和后缀 的 最长长度为2.
选择str匹配不成功的c和ptr[next[5-1]]即(ptr[2])进行匹配。
str:abcabcabe
ptr: abcabe
匹配成功。

附上代码:

#include<stdio.h>#include<string>#define M 1000#define N 100 int * getNext(char *str ,int len){    int next[M];    int j=1;    next[0] = 0;    for(int i = 1;i<len;i++) {        j = next[i-1];        if(str[j] == str[i]) {            next[i]=next[i-1]+1;        }else{            next[i] = 0;        }    }    return next;}int KMP(char str[],int sLen,char ptr[],int pLen){    int j = 0;    int *next;    next=getNext(ptr,pLen);    for(int i =0 ;i<sLen;i++){        if(str[i] == ptr[j]) {            j++;        }else{            j=next[j-1];        }        if(j==pLen) {            return i-j+1;        }    }    return -1;}void main(){    char str[M];    char ptr[N];    gets(str);    gets(ptr);    printf("%d",KMP(str,strlen(str),ptr,strlen(ptr)));}
原创粉丝点击