14 串实例

案例分析

病毒感染检测

分析:患者的DAN和病毒DNA均是由一些字母组成的字符串序列,要检测某种病毒DAN序列是否在患者的DNA序列中出现过,实际上就是字符串的模式匹配问题。可以使用BF算法或者KMP算法。与一般的模式匹配问题不同的是:病毒的DNA序列是环状的。

实现:假设病毒DNA的序列长度为m,因为病毒DNA是环状的,所以为了从任意起点线性的取到每个可行的长度为m的模式串。可将存储病毒DNA序列的字符串长度扩大为2m,即将病毒DNA序列连续存储2次。然后循环m次,依次取得每个长度为m的环状字符串,将此字符串作为模式串,将人的DNA序列作为主串,调用BF算法或者是KMP进行模式匹配。只要匹配成功,即可中止循环,表明该人感染了对应的病毒;否则,循环m次结束循环时,可通过BF算法的返回值判断该人是否感染了对应的病毒

#include<iostream>
#include<cstring>
using namespace std;
//串的定长顺序存储结构
#define MAXLEN 255  //串的最大长度
typedef struct{
	char ch[MAXLEN];
	int length;  //串的当前长度
}SString;

//BF
int Index_BF(SString S,SString T,int pos){
	//返回模式T在主串S中第pos个位置开始第一次出现的位置,不存在,返回0
	//其中T非空
		int i=pos,j=0; //初始化 这里是从0开始的
		//两个串均为比较到串尾
		while(i<S.length&&j<T.length){
			if(S.ch[i]==T.ch[j]){
				++i;
				++j;
			}else{
				i=i-j+1; //指针后退重新开始匹配
				j=0;
			}
		}
		if(j>=T.length)
				return i-T.length;  //匹配成功
			else
				return 0;  //匹配失败
}
//这个数组中村存放的是匹配字符串的next值
int Next[254];
//这个next数组是KMP的重点
void GetNext(SString T,int next[]){
	//求模式串T的next值并存入到数组next中
	int len=T.length;  //串长
	int i=0,j=-1;
	next[0]=-1;
	while(i<len-1){
		if(j==-1||T.ch[i]==T.ch[j]){
			++i;
			++j;
			next[i]=j;
		}else{
			j=next[j];
		}
	}
}

int Index_KMP(SString S,SString T,int pos){
	//利用模式串T的next函数求T在主串S中第pos个字符之后的位置
	//T非空
	int i=pos-1,j=0;
	GetNext(T,Next);
	while(i<S.length&&j<S.length){
		if(S.ch[i]==T.ch[j]){
			++i;
			++j;
		}else{
			j=Next[j];
		}
	}
	if(j>=T.length)
		return i-T.length; //匹配成功
	else
		return 0; //匹配失败
}
bool Virus_detection(SString s1,SString s2){
	SString s,temp;
	s.length=s1.length*2;
	temp.length=s1.length;
	strcpy(s.ch,s1.ch);
	int i=s1.length,flag;
	for(int j=0;j<s1.length;j++){
		s.ch[i]=s1.ch[j];   //将病毒字符串长度扩大2倍
		i++;
	}
	s.ch[10]='\0';   //添加结束符号
	for(int i=0;i<s1.length;i++){
		for(int j=0;j<s1.length;j++){
			temp.ch[j]=s.ch[i+j];
		}
		temp.ch[s1.length]='\0';  //添加结束符号
		//flag=Index_BF(s2,temp,0);// 使用BF
		flag=Index_KMP(s2,temp,0);  //使用KMP
		if(flag)
			break;
	}
	if(flag)
		return true ;
	else
		return false;
}

int main(){
	 //假设病毒DNA序列为v_DNA 假设是环状的,人的DNA序列为p_DNA
	 SString v_DNA,p_DNA;
	 strncpy(v_DNA.ch,"abcde",sizeof(v_DNA.ch));
	 v_DNA.length=5;
	 strncpy(p_DNA.ch,"fehavbcdeadecx",sizeof(p_DNA.ch));
	 p_DNA.length=14;
	 bool ans=Virus_detection(v_DNA,p_DNA);
	 if(ans)
		 printf("YES\n");
	 else
		 printf("NO\n");
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

xuhuimingc

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值