案例分析
病毒感染检测
分析:患者的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"); }