
算法核心思想
在BF算法的基础上加以改进,BF算法中每次当前字符不相等时,主串S要回溯到其下一个字符处,模式串T要回溯到 j=0 位置进行下一趟的匹配。然而,大多数情况下,这种回溯是没有必要的,非常耗时且效率低,是一种蛮力的思想。
KMP算法在此基础上对其做了改进,就是增加了next数组,里面存放的值就是每次匹配失败后模式串T要回溯的下标位置,所以KMP算法的核心就在于如何求模式串T的next数组,至于后面的串匹配过程和BF算法原理一致。
 
代码
#include<iostream>
#include<cstring>
using namespace std;
int next[]={0};
//求next值
void getNext(char T[],int next[]){
	int j=0,k=-1;
	next[0]=-1;
	while(T[j]!='\0'){
		if(k==-1){
			next[++j]=0;
			k=0;
		}
		else if(T[j]==T[k]){
			k++;
			next[++j]=k;
		}else {
			k=next[k];
		}
	} 
} 
//串匹配
int KMP(char S[],char T[]){
	int i=0,j=0;
	while(S[i]!='\0'&&T[j]!='\0'){
		if(S[i]==T[j]){
			i++;
			j++;
		}else{
			j=next[j];//不相等时,模式串回溯到对应的next值下标位置
			if(j==-1){
				i++;
				j++;
			} 
		}
	} 
	//当模式串全部被遍历完后,说明匹配成功,返回匹配成功时的开始位置 
	if(T[j]=='\0'){
		return (i-strlen(T))+1;
	}else{
	    return 0;	
	}	
} 
 
int main(){
	char S[]="abcabcacb";
	char T[]="abcac";
	cout<<"S="<<S<<endl;
	cout<<"T="<<T<<endl;
	getNext(T,next);//获取模式串T的next数组值
	int n=KMP(S,T);
	cout<<"模式串T的next数组值为:"<<endl;
	for(int i=0;i<5;i++){
		cout<<next[i]<<"  ";
	}
	cout<<endl;
	if(n!=0){
		cout<<"串匹配成功,起始位置为"<<n<<endl; 
	}else{
		cout<<"串匹配失败!"<<endl;
	}
	return 0;
} 运行

这里推荐一篇深入分析KMP算法的优质文章,三金大佬写的!
KMP算法真的有这么难吗?(清晰详细版) https://blog.csdn.net/QAZJOU/article/details/126765353?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522167538890716800215074340%2522%252C%2522scm%2522%253A%252220140713.130102334.pc%255Fall.%2522%257D&request_id=167538890716800215074340&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2~all~first_rank_ecpm_v1~rank_v31_ecpm-1-126765353-null-null.142^v72^insert_down4,201^v4^add_ask&utm_term=%E4%B8%89%E9%87%91kmp%E7%AE%97%E6%B3%95&spm=1018.2226.3001.4187END.
https://blog.csdn.net/QAZJOU/article/details/126765353?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522167538890716800215074340%2522%252C%2522scm%2522%253A%252220140713.130102334.pc%255Fall.%2522%257D&request_id=167538890716800215074340&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2~all~first_rank_ecpm_v1~rank_v31_ecpm-1-126765353-null-null.142^v72^insert_down4,201^v4^add_ask&utm_term=%E4%B8%89%E9%87%91kmp%E7%AE%97%E6%B3%95&spm=1018.2226.3001.4187END.


















