首先,我们需要理解KMP算法的基本思想。KMP算法是一种改进的字符串匹配算法,它的主要思想是利用已经部分匹配的这个有效信息,使得后续的匹配中,尽量减少字符串的回溯,提高匹配效率。
KMP算法的关键在于通过一个next数组,保存模式串中前后缀的最长的共有元素的长度。当模式串中的字符失配时,模式串向右移动的位数为:已匹配的字符数 - 失配字符对应的next值。
下面是KMP算法的伪代码:
1. 初始化主串S和模式串T的指针i和j为1,i不回溯,j回溯到next[j]的位置。
2. 如果j=0(模式串的第一个字符就和主串当前位置的字符不相等),则i++,j++,继续比较下一个字符。
3. 如果j=T.length(模式串全部匹配),则匹配成功,返回i-T.length。
4. 如果S[i]等于T[j],则i++,j++,继续比较下一个字符。
5. 如果S[i]不等于T[j],则j回溯到next[j]的位置,如果此时j=0,则i++,j++。
下面是C++代码:
#include "stdio.h"
#include "stdlib.h"
#include "iostream"
#define MAXSTRLEN 255
typedef unsigned char SString[MAXSTRLEN+1];
void get_next(SString T, int next[]) {
int i = 1, j = 0;
next[1] = 0;
while (i < T[0]) {
if (j == 0 || T[i] == T[j]) {
++i;
++j;
next[i] = j;
} else {
j = next[j];
}
}
}
int Index_KMP(SString S, SString T, int pos) {
int i = pos;
int j = 1;
int next[MAXSTRLEN];
get_next(T, next);
while (i <= S[0] && j <= T[0]) {
if (j == 0 || S[i] == T[j]) {
++i;
++j;
} else {
j = next[j];
}
}
if (j > T[0]) {
return i - T[0];
} else {
return 0;
}
}
int main() {
SString T, S;
int i, j, n;
char ch;
int pos;
scanf("%d", &n);
ch = getchar();
for (j = 1; j <= n; j++) {
ch = getchar();
for (i = 1; i <= MAXSTRLEN && (ch != '\n'); i++) {
S[i] = ch;
ch = getchar();
}
S[0] = i - 1;
ch = getchar();
for (i = 1; i <= MAXSTRLEN && (ch != '\n'); i++) {
T[i] = ch;
ch = getchar();
}
T[0] = i - 1;
pos = Index_KMP(S, T, 1);
printf("%d\n", pos);
}
return 0;
}
这段代码首先定义了一个get_next函数,用于计算模式串T的next数组。然后定义了一个Index_KMP函数,用于在主串S中查找模式串T的位置。最后在main函数中,读取n对主串和模式串,然后对每一对主串和模式串,调用Index_KMP函数进行匹配,并输出匹配的位置。
标签:匹配,int,模式,next,++,算法,KMP,8592 From: https://blog.csdn.net/huang1xiao1sheng/article/details/142492925