KMP模式匹配

来源:互联网 发布:单词社交网络pdf 编辑:程序博客网 时间:2024/05/06 02:27
# include <stdio.h>
# include <stdlib.h>
/*求字符串的长度*/
int getLength(char ch[]){
int i=0;
while(ch[i]!='\0'){
i++;
}
    return i;
}
int *Next(char ch[]){
int m=getLength(ch);
int *N = new int[m];
N[0]=0;
for(int i=1;i<m;i++)//分析P的每一个位置i
{
int k = N[i-1];//第i-1个位置的最长前缀长度
//以下while语句递推决定合适的前缀位置k
while(k>0&&ch[i]!=ch[k])
k=N[k-1];
//根据P[i]比较第K位置前缀字符,决定N[i]
if(ch[i]==ch[k])
N[i]=k+1;
else
N[i]=0;
}
return N;
}
int KMP_FindPat(char txt[],char pat[],int *N,int startindex,int offset[]){
//假设已经计算出Pat的特征数组N,作为输入参数
//txt末尾再倒数一个模版长度的位置
int LastIndex = getLength(txt)-getLength(pat);
if((LastIndex-startindex)<0){
return -1;//startindex过大无法匹配成功。
}
int c = 0;//记录匹配成功次数         offset[]记录每次匹配成功的在txt中的起始位置
int i;//i是执行txt内部的游标
int j=0;//j是指向pat内部的游标
//txt游标i循环加1
for(i=startindex;i<getLength(txt);i++){
//若当前位置的字符不同,则用N循环求当前的j
//用于将pat的恰当位置与txt的i位置对准
while(pat[j]!=txt[i]&&j>0)
j=N[j-1];
//若pat[j]和txt[i]相同,继续下一步循环
if(pat[j]==txt[i])j++;
//匹配成功返回txt字串的开始位置
if(j==getLength(pat))
//return i-j+1;
offset[c++]=i-j+1;
}
return c;//txt和pat整个匹配失败,函数返回值为负;改为返回匹配成功次数
}
void main(){
char txt[] = "abcdefhefghefgk";
char pat[] = "efg";
int *offset = new int[2];
    int c = KMP_FindPat(txt,pat,Next(pat),0,offset);
printf("%d,%d,%d",c,offset[0],offset[1]);
}
原创粉丝点击