KMP算法主要是两个步骤:
1:Next(char *p,int n[])函数计算模式串各值的部分匹配串长度。
Next函数:
void Next(char *p,int n[]){
int m = strlen(p); /*n[j]的值表示模式串在j位置的部分匹配串长度*/
n[0] = 0; /*0位置分匹配串长度为0*/
int i = 1,j = 0;
while(i<m){
if(p[i]==p[j]){
n[i] = j+1;
i++;j++;
}
else if(j>0) j = n[j-1];
else n[i++] = 0;
}
}
2:根据Next函数,用KMP_match(char *T,char *P)函数计算匹配位置。
KMP_match函数:
int KMP_match(char *T,char *P) {
int n = strlen(T); //目标串长度
int m = strlen(P); //模式串长度
int str[100];
Next(P,str); //计算待处理的模式串各值的部分匹配串长度
int i = 0,j = 0;
while(i<n){
if(T[i]==P[j]){
if(j==m-1) return i-j; //已匹配完成,返回目标串中匹配的位置
else{
i++;j++;
}
}
else{
if(j>0) j = str[j-1]; //移动到部分匹配串
else i++; //失配,此时j = 0,目标串往前移位
}
}
return -1;
}
完整代码:
#include <iostream>
#include <cstdio>
#include <string.h>
/*Next函数计算模式串各值的部分匹配串长度*/
void Next(char *p,int n[]){
int m = strlen(p); /*n[j]的值表示模式串在j位置的部分匹配串长度*/
n[0] = 0; /*0位置分匹配串长度为0*/
int i = 1,j = 0;
while(i<m){
if(p[i]==p[j]){
n[i] = j+1;
i++;j++;
}
else if(j>0) j = n[j-1];
else n[i++] = 0;
}
}
int KMP_match(char *T,char *P) {
int n = strlen(T); //目标串长度
int m = strlen(P); //模式串长度
int str[100];
Next(P,str); //计算待处理的模式串各值的部分匹配串长度
int i = 0,j = 0;
while(i<n){
if(T[i]==P[j]){
if(j==m-1) return i-j; //已匹配完成,返回目标串中匹配的位置
else{
i++;j++;
}
}
else{
if(j>0) j = str[j-1]; //移动到部分匹配串
else i++; //失配,此时j = 0,目标串往前移位
}
}
return -1;
}
int main(int argc, char** argv) {
char T[100],P[100];
scanf("%s",T);
scanf("%s",P);
printf("%d",KMP_match(T,P));
return 0;
}