数据结构——基于字符串模式匹配算法的病毒感染检测
實(shí)驗(yàn)四 基于字符串模式匹配算法的病毒感染檢測(cè)
【實(shí)驗(yàn)?zāi)康摹?br /> 1.掌握字符串的順序存儲(chǔ)表示方法。
2.掌握字符串模式匹配BF算法和KMP算法的實(shí)現(xiàn)。
【實(shí)驗(yàn)內(nèi)容】
問(wèn)題描述
醫(yī)學(xué)研究者最近發(fā)現(xiàn)了某些新病毒,通過(guò)對(duì)這些病毒的分析,得知它們的DNA序列都是環(huán)狀的。現(xiàn)在研究者已收集了大量的病毒DNA和人的DNA數(shù)據(jù),想快速檢測(cè)出這些人是否感染了相應(yīng)的病毒。為了方便研究,研究者將人的DNA和病毒DNA均表示成由一些字母組成的字符序列,然后檢測(cè)某種病毒DNA序列是否在患者的DNA序列中出現(xiàn)過(guò)。如果出現(xiàn)過(guò),則此人感染了該病毒,否則沒(méi)有感染。例如,假設(shè)病毒的DNA序列為baa,患者1的DNA序列為aaabbba,則感染;患者2的DNA序列為babbba,則未感染。(注意,人的DNA序列是線性的,而病毒的DNA序列是環(huán)狀的。)
輸入要求
多組數(shù)據(jù),每組數(shù)據(jù)有1行,為序列A和B,A對(duì)應(yīng)病毒的DNA序列,B對(duì)應(yīng)人的DNA序列。A和B都為“0”時(shí)輸入結(jié)束。
輸入樣例
abbab abbabaab
baa cacdvcabacsd
abc def
0 0
輸出樣例
YES
YES
NO
【實(shí)驗(yàn)提示】
此實(shí)驗(yàn)內(nèi)容即要求實(shí)現(xiàn)教材算法的具體案例。利用BF算法來(lái)實(shí)現(xiàn)字符串的模式匹配過(guò)程的,效率較低,。利用KMP算法完成模式匹配以提高算法的效率。
解決方法1:暴力算法
#include <stdio.h> // printf(); scanf() #include <stdlib.h> // exit() #include <malloc.h> // malloc() #include <time.h> // srand((unsigned)time(NULL)); #include <string.h>#define TRUE 1 #define FALSE 0 #define OK 1 #define ERROR 0typedef int Status;typedef int ElemType;#define MAXSTRLEN 255 typedef unsigned char SString[MAXSTRLEN + 1]; Status StrAssign(SString &T, char *chars) {if(strlen(chars) > MAXSTRLEN)return ERROR;else {T[0] = strlen(chars); for(int i=1; i<=T[0]; i++)T[i] = *(chars+i-1);return OK;} }Status StrCopy(SString &T, SString S) {for(int i=0; i<=S[0]; i++)T[i] = S[i];return OK; }int StrLength(SString S) {return S[0]; }int index(SString S,SString T,int pos) {int i=pos,j=1;while(i<=S[0]&&j<=T[0]){if(S[i]==T[j]){++i;++j;}else {i=i-j+2;j=1;}}if(j>T[0])return i-T[0];else return 0;} int main() { int flag[100];int w=0; int x;int number;int pos;char c[MAXSTRLEN+1],d[MAXSTRLEN+1];SString S;SString T;SString Z;do{scanf("%s",c);scanf("%s",d);StrAssign(S, c);StrAssign(T, d);char str[T[0]];for(int i=0; i<=S[0]; i++)str[i] = T[i+1];int i=0;Z[0]=T[0];for(i=0;i<T[0];i++){for(int j=1;j<=T[0];j++){Z[j]=str[(j+i)%(T[0])]; }number=index(S,Z,pos);if(number!=0&&strcmp(c,"0")!=0&&strcmp(d,"0")!=0){flag[w++]=1;break; } }if(i==T[0]&&strcmp(c,"0")!=0&&strcmp(d,"0")!=0)flag[w++]=0;}while(strcmp(c,"0")!=0&&strcmp(d,"0")!=0);for(int e=0;e<w;e++){if(flag[e]==1)printf("YES\n");//即在人體dna中找到與病毒dna相同的序列 elseprintf("NO\n");//即在人體dna中找到與病毒dna相同的序列 } return 0;}解決方法2:kmp算法
#include <stdio.h> // printf(); scanf() #include <stdlib.h> // exit() #include <malloc.h> // malloc() #include <time.h> // srand((unsigned)time(NULL)); #include <string.h>#define TRUE 1 #define FALSE 0 #define OK 1 #define ERROR 0typedef int Status; typedef int ElemType; #define MAXSTRLEN 255 typedef unsigned char SString[MAXSTRLEN + 1];Status StrAssign(SString &T, char *chars) {if(strlen(chars) > MAXSTRLEN)return ERROR;else {T[0] = strlen(chars); // 0號(hào)單元存放串的長(zhǎng)度for(int i=1; i<=T[0]; i++)T[i] = *(chars+i-1);return OK;} }Status StrCopy(SString &T, SString S) {for(int i=0; i<=S[0]; i++)T[i] = S[i];return OK; }int StrLength(SString S) {return S[0]; }void get_next(SString T,int next[]) {int j; int i=1;next[1]=0;j=0;while(i<T[0]){if(j==0||T[i]==T[j]){i++;j++;next[i]=j;}else j=next[j];} }int Index_KMP(SString S,SString T,int pos) { int next[MAXSTRLEN+1]; get_next(T,next);int i=pos; int j=1;while(i<=S[0]&&j<=T[0])//i j都不超過(guò)其串的長(zhǎng)度{//失配 //1:失配,當(dāng)j==0時(shí),則目標(biāo)主串的檢測(cè)指針前進(jìn)一位,模式串檢測(cè)指針回到T[1].進(jìn)行下一趟的比較//2:失配,當(dāng)j>0時(shí),那么在下一趟比較時(shí),模式串的起始位置為Tnext[j],目標(biāo)主串S的檢測(cè)指針不回溯,仍然指向上一趟失配的位置 if(j==0||S[i]==T[j]){++i;++j;//繼續(xù)比較后繼字符 }else j=next[j];//模式串向右移動(dòng) }if(j>T[0]) return i-T[0];//匹配成功 else return 0; }int main() { int flag[100];int w=0; int x;int number;int pos;char c[MAXSTRLEN+1],d[MAXSTRLEN+1];SString S;SString T;SString Z;do{scanf("%s",d); scanf("%s",c);StrAssign(S, c);StrAssign(T, d);char str[T[0]];for(int i=0; i<=S[0]; i++)str[i] = T[i+1];int i=0;Z[0]=T[0];for(i=0;i<T[0];i++){for(int j=1;j<=T[0];j++){Z[j]=str[(j+i)%(T[0])]; }//StrPrint(Z); //printf("\n");number=Index_KMP(S,Z,pos);if(number!=0&&strcmp(c,"0")!=0&&strcmp(d,"0")!=0){flag[w++]=1;break; } }if(i==T[0]&&strcmp(c,"0")!=0&&strcmp(d,"0")!=0)flag[w++]=0;}while(strcmp(c,"0")!=0&&strcmp(d,"0")!=0);for(int e=0;e<w;e++){if(flag[e]==1)printf("YES\n");//即在人體dna中找到與病毒dna相同的序列 elseprintf("NO\n");//即在人體dna中找到與病毒dna相同的序列 } return 0;} 解決方法3:kmp算法改進(jìn)版```c #include <stdio.h> // printf(); scanf() #include <stdlib.h> // exit() #include <malloc.h> // malloc() #include <time.h> // srand((unsigned)time(NULL)); #include <string.h>#define TRUE 1 #define FALSE 0 #define OK 1 #define ERROR 0 typedef int Status; typedef int ElemType; #define MAXSTRLEN 255 typedef unsigned char SString[MAXSTRLEN + 1]; Status StrAssign(SString &T, char *chars) {if(strlen(chars) > MAXSTRLEN)return ERROR;else {T[0] = strlen(chars); for(int i=1; i<=T[0]; i++)T[i] = *(chars+i-1);return OK;} }int StrLength(SString S) {return S[0]; }void get_nextval(SString T,int nextval[]) {int j; int i=1;nextval[1]=0;j=0;while(i<T[0]){if(j==0||T[i]==T[j]){i++;j++;if(T[i]!=T[j])nextval[i]=j;else nextval[i]=nextval[j];}else j=nextval[j];} }int Index_KMP_val(SString S,SString T,int pos) { int nextval[MAXSTRLEN+1]; get_nextval(T,nextval);int i=pos; int j=1;while(i<=S[0]&&j<=T[0])//i j都不超過(guò)其串的長(zhǎng)度{//失配 //1:失配,當(dāng)j==0時(shí),則目標(biāo)主串的檢測(cè)指針前進(jìn)一位,模式串檢測(cè)指針回到T[1].進(jìn)行下一趟的比較//2:失配,當(dāng)j>0時(shí),那么在下一趟比較時(shí),模式串的起始位置為Tnext[j],目標(biāo)主串S的檢測(cè)指針不回溯,仍然指向上一趟失配的位置 if(j==0||S[i]==T[j]){++i;++j;//繼續(xù)比較后繼字符 }else j=nextval[j];//模式串向右移動(dòng) }if(j>T[0]) return i-T[0];//匹配成功 else return 0; }int main() { int flag[100];//用于計(jì)算循環(huán)數(shù)組 每次的結(jié)果 int w=0; //用于統(tǒng)計(jì)flag數(shù)組 int x;int number;int pos;char c[MAXSTRLEN+1],d[MAXSTRLEN+1];SString S;SString T;SString Z;do{scanf("%s",d); scanf("%s",c);StrAssign(S, c);StrAssign(T, d);char str[T[0]];for(int i=0; i<=S[0]; i++)str[i] = T[i+1];int i=0;Z[0]=T[0];for(i=0;i<T[0];i++){for(int j=1;j<=T[0];j++){Z[j]=str[(j+i)%(T[0])]; }number=Index_KMP_val(S,Z,pos);if(number!=0&&strcmp(c,"0")!=0&&strcmp(d,"0")!=0){flag[w++]=1;break; } }if(i==T[0]&&strcmp(c,"0")!=0&&strcmp(d,"0")!=0)flag[w++]=0;}while(strcmp(c,"0")!=0&&strcmp(d,"0")!=0);for(int e=0;e<w;e++){if(flag[e]==1)printf("YES\n");//即在人體dna中找到與病毒dna相同的序列 elseprintf("NO\n");//即在人體dna中找到與病毒dna相同的序列 } return 0;}總結(jié)
以上是生活随笔為你收集整理的数据结构——基于字符串模式匹配算法的病毒感染检测的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 任天堂下周推出“Switch Onlin
- 下一篇: 数据结构——模式匹配kmp算法