病毒感染检测(数据结构串,c语言版)

一、实验题目

医学研究者最近发现了某些新病毒,通过对这些病毒的分析,得知它们的 DNA 序列都是环状的。现在研究者巳收集了大量的病毒 DNA 和人的 DNA 数据,想快速检测出这些人是否感染了相应的病毒。为了方便研究,研究者将人的 DNA 和病毒 DNA 均表示成由一些字母组成的字符串序列,然后检测某种病毒 DNA 序列是否在患者的 DNA 序列中出现过,如果出现过,则此人感染了该病毒,否则没有感染。 例如, 假设病毒的 DNA 序列为 baa, 患者 1 的 DNA 序列为 aaabbba,则感染, 患者 2 的 DNA 序列为 babbba, 则未感染。(注意,人的 DNA 序列是线性的, 而病毒的DNA 序列是环状的)图 4.1 数据对应的输出结果如图 4.2 所示。

数据结果

1.案例分析

因为患者的 DNA 和病毒 DNA 均是由一些字母组成的字符串序列, 要检测某种病毒 DNA 序列是否在患者的 DNA 序列中出现过 , 实际上就是字符串的模式匹配问题。可以利用 BF 算法,也可以利用更高效的KMP算法。但与一般的模式匹配问题不同的是,此案例中病毒的 DNA 序列是环状的, 这样需要对传统的 BF 算法或KMP算法进行改进。
下面给出利用 BF 算法实现检测的方案。

2.案例实现

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

3.算法步骤

1.从文件中读取待检测的任务数 num。
2.根据 num个数依次检测每对病毒DNA和人的DNA是否匹配,循环 num次,执行以下操作:
• 从文件中分别读取一对病毒DNA序列和人的DNA序列;
• 设置一个标志性变量flag, 用来标识是否匹配成功,初始为0, 表示未匹配;
• 病毒DNA序列的长度是 m, 将存储病毒DNA序列的字符串长度扩大为 2m, 将病毒DNA序列连续存储两次;
• 循环m次,重复执行以下操作:
► 依次取得每个长度为m的病毒DNA环状字符串;
► 将此字符串作为模式串,将人的DNA序列作为主串, 调用BF算法进行模式匹配,将匹配结果返回赋值给flag;
► 若flag非0, 表示匹配成功, 中止循环,表明该人感染了对应的病毒。
• 退出循环时, 判断flag的值,若flag非0, 输出 “YES” , 否则,输出 “NO”。

4.算法描述

void Virus detection () 
{//利用 BF 算法实现病毒检测
	ifstream inFile("病毒感染检测输入数据. txt"); 
	ofstream outFile("病毒感染检测输出结果. txt"); 
	inFile>>num; //读取待检测的任务数
	while(num--) //依次检测每对病毒 DNA 和人的 DNA 是否匹配
	{
		inFile>>Virus.ch+1; //读取病毒 DNA 序列, 字符串从下标 1 开始存放
		inFile>>Person.ch+1; //读取人的 DNA 序列
		Vir=Virus.ch; //将病毒 DNA 临时暂存在Vir中,以备输出
		flag=0; //用来标识是否匹配,初始为0, 匹配后为非0
		m=Virus.length; //病毒 DNA 序列的长度是 m
		for(i=m+1, j=l; j<=m; j++) 
			Virus.ch[i++]=Virus.ch[j]; //将病毒字符串的长度扩大2倍
		Virus.ch[2*m+1]='\0'; //添加结束符号
		for(i=0;i<m;i++) //依次取得每个长度为m 的病毒 DNA 环状字符串 temp
		{
			for (j=1; j<=m; j ++) temp.ch[j]=Virus.ch[i+j];
			temp.ch[m+1]='\0'; //添加结束符号
			flag=Index_BF (Person, temp, 1); //模式匹配
			if(flag) break; //匹配即可退出循环
		}// for 
		if (flag) outFile<<Vir+l<<" "<<Person.ch+1<<" "<<"YES"<<endl; 
		else outFile<<Vir+l<<" "<<Person.ch+1<<" "<<"NO"<<endl; 
	}//while
}

二、工具环境

Window10操作系统,Microsoft Visual C++2010学习版 集成开发环境,C语言

三、实验代码

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
  
#define MAXLEN 255	   //串的最大长度

typedef struct{ 
	char ch[MAXLEN+1]; //存储串的一维数组
	int length; //串的当前长度
}SString; 

typedef struct{ 
	char Results[MAXLEN+1];//存放检测结果
}Detection;   

int  Index_BF(SString S,SString T,int pos); 
void Virus_detection(SString S[],SString T[],int num,Detection detection[]);

int main()
{
	Detection detection[10];
	SString S[10]=
	{
		{"bbaabbba",8},
		{"aaabbbba",8},
		{"abceaabb",8},
		{"abaabcea",8},
		{"cdabbbab",8},
		{"cabbbbab",8},
		{"bcdedbda",8},
		{"bdedbcda",8},
		{"cdcdcdec",8},
		{"cdccdcce",8}
	};
	SString T[10]=
	{
		{"baa"  ,3},
		{"baa"  ,3},
		{"aabb" ,4},
		{"aabb" ,4},
		{"abcd" ,4},
		{"abcd" ,4},
		{"abcde",5},
		{"acc"  ,3},
		{"cde"  ,3},
		{"cced" ,4}
	};
	int num=10,i;
	Virus_detection(S,T,num,detection);
	printf("\t病毒DNA 人DNA \t检测结果\n");
	for(i=0;i<10;i++){
		printf("\t%-5s \t%s   %s\n",T[i].ch,S[i].ch,detection[i].Results);
	}
	return 0;
}

int Index_BF(SString S,SString T,int pos)
{//返回模式T在主串s中第pos个字符开始第一次出现的位置.若不存在,则返回值为0
	int i,j;
	i=pos; j=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 1;//匹配成功
	else return 0; //匹配失败
}

void Virus_detection(SString S[],SString T[],int num,Detection detection[]) 
{//利用 BF 算法实现病毒检测
	SString Person,Virus,temp;
	int i,j,m,flag,k=0;
	char Vir[10];
	while(num--) //依次检测每对病毒 DNA 和人的 DNA 是否匹配
	{
		Person=S[k];
		Virus=T[k];
		strcpy(Vir,Virus.ch); //将病毒 DNA 临时暂存在Vir中,以备输出
		flag=0; //用来标识是否匹配,初始为0, 匹配后为非0
		m=Virus.length; //病毒 DNA 序列的长度是 m
		for(i=m, j=0; j<m; j++){
			Virus.ch[i++]=Virus.ch[j]; //将病毒字符串的长度扩大2倍
		}
		Virus.ch[2*m]='\0'; //添加结束符号
		for(i=0;i<m;i++) //依次取得每个长度为m 的病毒 DNA 环状字符串 temp
		{
			for (j=0; j<m; j++) temp.ch[j]=Virus.ch[i+j];
			temp.ch[m]='\0'; //添加结束符号
			temp.length=Virus.length;
			flag=Index_BF (Person, temp, 0); //模式匹配
			if(flag) break; //匹配即可退出循环
		}// for 
		if(flag) strcpy(detection[k].Results,"YES");
		else strcpy(detection[k].Results,"NO");
		k++;
	}//while
}
评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值