/* next数组是KMP算法的关键,next数组的作用是:当模式串T和主串S失配
* ,next数组对应的元素指导应该用T串中的哪一个元素进行下一轮的匹配
* next数组和T串相关,和S串无关。KMP的关键是next数组的求法。
*
* ———————————————————————————————————————————————————————————————————
* | T | 9 | a | b | a | b | a | a | a | b | a |
* ————————————————————————————————————————————————————————————————————
* |index| 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 |
* ————————————————————————————————————————————————————————————————————
* |next | X | 0 | 1 | 1 | 2 | 3 | 4 | 2 | 2 | 3 | * ————————————————————————————————————————————————————————————————————————
*
step 0:
* j = 0; i = 1; next[1] = 0
* | 1 2 3 4 5 6 7 8 9 10
* —————————————————————————————————————————————————————————————————————
* i = | 1
* j = | 0
*
step 1:
* j == 0;-->i = 2;j = 1;next[2] = 1;
* | 1 2 3 4 5 6 7 8 9 10
* —————————————————————————————————————————————————————————————————————
* i = | 1 2
* j = | 0 1
*
step 2:
* T[2] != T[1];--> j = next[1]-->j = 0;i = 2
* | 1 2 3 4 5 6 7 8 9 10
* —————————————————————————————————————————————————————————————————————
* i = | 1 2 2
* j = | 0 1 0
*
step 3:
* j == 0 --> j++;i++;--> j = 1;i = 3;next[3] = 1
* | 1 2 3 4 5 6 7 8 9 10
* —————————————————————————————————————————————————————————————————————
* i = | 1 2 2 3
* j = | 0 1 0 1
*
step 4:
* T[3] == T[1];-->i++;j++;-->i=4,j=2; next[4] = 2
* | 1 2 3 4 5 6 7 8 9 10
* —————————————————————————————————————————————————————————————————————
* i = | 1 2 2 3 4
* j = | 0 1 0 1 2
*
step 5:
* T[4] == T[2];-->i++;j++-->i=5,j=3-->next[5]=3
* | 1 2 3 4 5 6 7 8 9 10
* —————————————————————————————————————————————————————————————————————
* i = | 1 2 2 3 4 5
* j = | 0 1 0 1 2 3
*
step 6:
* T[5] == T[3];-->i++,j++;-->i=6,j=4;next[6]=4;
* | 1 2 3 4 5 6 7 8 9 10
* —————————————————————————————————————————————————————————————————————
* i = | 1 2 2 3 4 5 6
* j = | 0 1 0 1 2 3 4
*
step 7:
* T[6] != T[4];-->j = next[j];-->j=2;
* | 1 2 3 4 5 6 7 8 9 10
* —————————————————————————————————————————————————————————————————————
* i = | 1 2 2 3 4 5 6 6
* j = | 0 1 0 1 2 3 4 2
*
step 8:
* T[2] != T[6];-->j = next[j];-->j = 1;
* | 1 2 3 4 5 6 7 8 9 10
* —————————————————————————————————————————————————————————————————————
* i = | 1 2 2 3 4 5 6 6 6
* j = | 0 1 0 1 2 3 4 2 1
*
step 9:
* T[1] == T[6];-->i++,j++;-->i=7,j=2;next[7]=2;
* | 1 2 3 4 5 6 7 8 9 10
* —————————————————————————————————————————————————————————————————————
* i = | 1 2 2 3 4 5 6 6 6 7
* j = | 0 1 0 1 2 3 4 2 1 2
*
step 10:
* T[2]!=[7];-->j=next[j];-->j=1;
* | 1 2 3 4 5 6 7 8 9 10 11
* ———————————————————————————————————————————————————————————————————————————————————
* i = | 1 2 2 3 4 5 6 6 6 7 7
* j = | 0 1 0 1 2 3 4 2 1 2 1
*
step 11:
* T[1]==T[7];-->i++,j++;-->i=8,j=2;-->next[8]=2;
* | 1 2 3 4 5 6 7 8 9 10 11 12
* ———————————————————————————————————————————————————————————————————————————————————
* i = | 1 2 2 3 4 5 6 6 6 7 7 8
* j = | 0 1 0 1 2 3 4 2 1 2 1 2
*
step 12:
* T[2]==T[8];-->i++,j++;-->i=9,j=3;next[9]=3;
* | 1 2 3 4 5 6 7 8 9 10 11 12
* ———————————————————————————————————————————————————————————————————————————————————
* i = | 1 2 2 3 4 5 6 6 6 7 7 8
* j = | 0 1 0 1 2 3 4 2 1 2 1 2
* */
/* 模式串:ababaadacc
* 前缀和后缀的概念:
* 前缀:除去最后一个元素之外的所有包含第一个元素的连续字符串
* 对于模式串中的d则前缀有:a ab aba abab ababa
* 后缀:除去第一个元素之外的所有的包含最后一个元素的连续字符串
* 对于模式串中的d则前缀有:a aa baa abaa babaa
* */
#include<stdio.h>
//next数组的作用: 当模式串匹配失败的时候,next数组的相对应的元素指示
// 要从模式串的哪个位置开始和当前的主串的失配的元素开
// 始进行下一轮的匹配。
void getNext(char* T, int* next){
int i = 1; //i的值是将要计算的next的下标
int j = 0; //前缀
next[1] = 0;
while( i <= 9 ){
if( 0 == j || T[i] == T[j] ){
//T[i] == T[j]则向后匹配
//当前的next[i]的值已经确定为j
//j==0或为初始,或者是没有匹配的前缀
//此时i和j自加
i++;
j++;
next[i] = j;
}
else{
j = next[j]; //next的作用:当T[j]和T[i]失配,next[j]的值
//指示的下一次要进行匹配的位置,有点像递归。
}
}
}
int KMP(char* S, char* T, int startPosition){
int i = startPosition;
int j = 1;
int next[30];
getNext(T,next);
while( i <= 17 && j <= 9 ){ //j>则说明匹配成功了,i>则说明失败了
if( j == 0 || S[i] == T[j] ){ //j==0;可以理解为要重新开始
i++;
j++;
}
else{
j = next[j];
}
}
if( j > 9 ){
return i - 9;
}
else
return 0;
}
int main(){
char S[20] = " absfeafdababaaaba";
char T[20] = " ababaaaba";
int result;
result = KMP(S,T,1);
printf("the position is %d\n",result);
return 0;
}
KMP算法
最新推荐文章于 2023-04-09 17:43:52 发布