数据结构实验任务三:利用KMP算法实现查询主串中是否含有目标子串

改代码为数据结构试验任务三:利用KMP算法实现查询主串中是否含有目标子串;

需要考虑DNA都是环状的,应用两个字符串实现环状结构。

#include <iostream>
#define MaxC 20
#define MaxE 20
using namespace std;


class Exp{		//定义样本类 

	private:
		int used=0;				//是否读取信息 
		char vir[MaxC];			//病毒DNA 
		char per[MaxC];			//人类DNA 
		int vsize;				//病毒DNA串长度 
		int psize;				//人类DNA串长度 
	public:
		int getvsize(){			//获取病毒长度 
			return vsize;
		}
		int getpsize(){			//获取人类DNA长度 
			return psize;
		}
		void setVir(char* a){	//设定病毒DNA 
			int i=0;
			while(a[i]!='\0'){
				vir[i] = a[i];
				i++;
			}
			vir[i] = '\0';
			vsize = i;
			used = 1;
		}
		void setPer(char* a){		//设定人类DNA 
			int i=0;
			while(a[i]!='\0'){
				per[i] = a[i];
				i++;
			}
			per[i] = '\0';
			psize=i;
			used = 1;
		}
		char* getVir(){				//获取病毒DNA 
			return vir;
		}
		char* getPer(){				//获取人类DNA 
			return per;
		}
		int Used(){					//返回该样本是否有效 
			return used;
		}
};

//函数声明
int KMP(char *sub,char* m ,int ns,int rm);		//KMP检查子串是否在主串内 
void Read(Exp *a);								//读取样本数据 
void PrintE(Exp *a);							//打印样本数据 
void Test(Exp *a); 								//进行样本检测 


int KMP(char *sub,char *m,int ns,int nm){
	 int next[MaxC];
	 int j=0;
	 next[0] = 0;
	 next[1] = 0;
	 for(int i=2;i<ns;i++){
	 	//总结 表示即为,若前字符的next位上的字符等于该字符,则该位为前next的值+1,否则为0
		 if(sub[i-1] == sub[next[i-1]])next[i] = next[i-1]+1;
		 else next[i] = 0; 

	 }
	 for(int i=0;i<nm;i++){
	 	//若母串的第i个数据与子串的第j个数据相同,则i++,j++ 
	 	while(m[i]==sub[j]&&j<ns){
	 		i++;
	 		j++;
		 }
		//出现母字符串中的元素成功与子字符串的最后 一个元素相同,则认为该字符串是母串的子串 
		if(j==ns)return 1;
		//如果不同,则将j复位于next[j]的位置 
		 j = next[j]; 
	 }
	 return 0;
}
//读取样本数据 
void Read(Exp* a){
	char v[MaxC],p[MaxC];
	for(int i=0;;i++){
		cout<<i+1<<":"; 
		cin>>v>>p;
		if(v[0]=='0'||p[0]=='0')break;
		a[i].setVir(v);
		a[i].setPer(p);
	} 
}
//打印样本数组 
void PrintE(Exp* a){
	for(int i=0;;i++){
		if(a[i].Used()==1){
			cout<<a[i].getVir()<<endl;
		}else break;
	} 
}
//检查样本 
void Test(Exp* a){
	char *tmpv,*tmpp;
	char test[MaxC*2];
	int nv,np,flag=0;
	char sub[MaxC];
	for(int i=0;;i++){
		//如果该样本已读取数据 
		if(a[i].Used()==1){
			//基础赋值 
			flag = 0;
			tmpv = a[i].getVir();
			tmpp = a[i].getPer();
			np = a[i].getpsize();
			nv = a[i].getvsize();
			//组成环状 
			for(int i=0;i<nv;i++){
			test[i] = tmpv[i];
			test[nv+i] = tmpv[i];
			}
			cout<<i+1<<":";
			//拼接序列并检测子串 
			for(int i=0;i<nv;i++){
				for(int j=0;j<nv;j++){
					sub[j] = test[i+j];
				}
				sub[nv]='\0';
				//KMP算法查询子串 
				if(KMP(sub,tmpp,nv,np)){	//结果为真 
					printf("Yes!\n");
					flag=1;				//标志无需再打印NO 
					break;				//无需再查询 
				} 
			}
			if(flag==0)
			printf("No!\n");			//所有序列均不为子串,打印NO! 
			
		}else break;
		
		
	}
}

int main(){
	Exp *a = new Exp[MaxE];	//创建目标样本数组 
	cout<<"Input the exps and end with '0':\n"; 
	Read(a);				//读取样本信息 
	//PrintE(a);			//打印样本数据(调试用)
		 	 printf("\n                  =================FZC===============                 \n\n");
	cout<<"Result:"<<endl; 
	Test(a);				//进行检测 
	return 0;
} 

改代码仅供参考,欢迎交流。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值