KMP算法

/* 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;
}


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值