继续讨论字符串匹配问题关于KMP算法的实现 juejin.cn/post/684490… KMP主要是利用一个数组回溯索引路径,我们用2层循环对比主字符串S位置i 与模式串T位置j 的字符对比
首先我们要生成一个next数组来存储对应的j需要回溯的位置
//----KMP 模式匹配算法---
//1.通过计算返回子串T的next数组;
void getNext(String T, int* next ){
// 注意 字符串从T[1] 开始 T[0] 为字符串长度
int j = 1;
int i = 0;
next[1] = 0;
//遍历T模式串, 此时T[0]为模式串T的长度;
//printf("length = %d\n",T[0]);
while (j < T[0]) {
//printf("i = %d j = %d\n",i,j);
if(i ==0 || T[i] == T[j]){
//T[i] 表示后缀的单个字符;
//T[j] 表示前缀的单个字符;
i++;j++;
next[j] = i;
}else
{
//如果字符不相同,则i值回溯;
i = next[i];
}
}
}
//----KMP 模式匹配算法---
//1.通过计算返回子串T的next数组;
//注意字符串T[0]中是存储的字符串长度; 真正的字符内容从T[1]开始;
void get_next(String T,int *next)
int count = 0;
//KMP 匹配算法(1)
//返回子串T在主串S中第pos个字符之后的位置, 如不存在则返回0;
int Index_KMP(String S,String T,int pos){
//i 是主串当前位置的下标准,j是模式串当前位置的下标准
int i = pos;
int j = 1;
//定义一个空的next数组;
int next[MAXSIZE];
for (i=0; i<MAXSIZE+1; i++) {
next[i] = 0;
}
NextPrint(next,MAXSIZE);
//对T串进行分析,得到next数组;
getNext(T, next);
for (int i =0; i<T[0]; i++) {
printf("%d",next[i]);
}
printf("next数组的值 \n");
count = 0;
//注意: T[0] 和 S[0] 存储的是字符串T与字符串S的长度;
//若i小于S长度并且j小于T的长度是循环继续;
while (i <= S[0] && j <= T[0]) {
//如果两字母相等则继续,并且j++,i++
if(j == 0 || S[i] == T[j]){
i++;
j++;
printf("%d 对比 %d \n",S[i],T[j]);
}else{
//如果不匹配时,j回退到合适的位置,i值不变;
j= next[j];
printf("不匹配 %d \n",j);
}
}
if (j > T[0]) {
return i-T[0];
}else{
return -1;
}
}
//输出Next数组值
void NextPrint(int next[],int length)
{
int i;
for(i=1;i<=length;i++)
printf("%d",next[i]);
printf("\n");
}