数据结构——KMP算法

版权声明:随便转哈,说明下出处~ https://blog.csdn.net/qq_40922859/article/details/83450305

课本知识和竞赛用的还是略微有些差别:

比如next数组的求法,虽说原理上一样(最长公共前后缀),但是表示起来还是有一点点区别:

比如: abcabaa

按照最长公共前后缀的求法:

先得到:0001211

之后去掉最后一位,得到000121,再把第一位赋值为-1;即-1000121,这个就是我们一般做oj题用的所谓next数组;

但是按照课本的求法:你会发现结果却是0111232,

#include<iostream>
#include<cstring>
#include<cstdio>
#include<cstring> 
using namespace std;
const int MAX=500;
int Next[MAX];
int nextval[MAX];
typedef struct{
	char ch[MAX+1];
	int length;
}SString;
int Index_KMP(SString S,SString T,int pos){
	int i=pos;
	int j=1;
	while(i<=S.length&&j<=T.length){
		if(j==0||S.ch[i]==T.ch[j]){
			++i;++j;
		}
		else 
		j=Next[j];
	}
	if(j>T.length) return i-T.length;
	else return 0;
}

void get_next(SString T,int Next[]){
	 int i=1;
	 Next[1]=0;
	 int j=0;
	 while(i<T.length){
	 	if(j==0||T.ch[i]==T.ch[j]){
	 		++i;++j;Next[i]=j;
		 }
		 else j=Next[j];
	 }
}
void get_nextval(SString T,int nextval[]){
	int i=1;
	nextval[1]=0;
	int j=0;
	while(i<T.length){
		if(j==0||T.ch[i]==T.ch[j]){
			++i;++j;
			if(T.ch[i]!=T.ch[j]){
				nextval[i]=j;
			}
			else nextval[i]=nextval[j];
		}
		else j=nextval[j];
	}
}
int main(){
	SString s,t;
	cout<<"请输入主串s"<<endl;
	cin>>s.ch+1;
	s.length=strlen(s.ch+1); 
	cout<<"请输入子串t"<<endl;
	cin>>t.ch+1; 
	t.length=strlen(t.ch+1);
	int m=s.length;
	int n=t.length;
    cout<<"主串为"<<endl;
    for(int i=1;i<=m;i++){
    	cout<<s.ch[i];
	}
	cout<<endl;
	cout<<"子串为"<<endl;
	for(int i=1;i<=n;i++){
    	cout<<t.ch[i];
	}
	cout<<endl;
	get_next(t,Next);
	cout<<"Next数组为"<<endl; 
	for(int i=1;i<=n;i++){
		cout<<Next[i];
	} 
	cout<<endl;
	get_nextval(t,nextval);
	cout<<"nextval数组为"<<endl; 
	for(int i=1;i<=n;i++){
		cout<<nextval[i];
	} 
	cout<<endl;
	int val=Index_KMP(s,t,1);
	if(val) cout<<"在"<<val<<"位置匹配成功"<<endl;
	else cout<<"匹配失败"<<endl; 
	return 0;
}

╮(╯_╰)╭,原始的才是最经典的。

猜你喜欢

转载自blog.csdn.net/qq_40922859/article/details/83450305