數據結構實驗病毒感染檢測問題(C++)

         醫學研究者最近發現了某些新病毒,通過對這些病毒的分析,得知他們的DNA序列都是環狀的。現在研究者已收集了大量的病毒DNA和人的DNA數據,想快速檢測出這些人是否感染了相應的病毒。爲了方便研究,研究者將人的DNA和病毒DNA均表示成由一些字母組成的字符串序列,然後檢測某種病毒DNA序列是否在患者的DNA序列中出現過,如果出現過,這此人感染了該病毒,否則沒有感染。例如,假設病毒的DNA序列爲baa,患者1的DNA序列爲aaabbba,則感染。患者2的DNA序列爲babbba,則未感染。(注意:人的DNA序列是線性的,而病毒的DNA序列是環狀的)。

         研究者將待檢測的數據保存在一個文本文件中,文件格式和內容規定如下:文件有num+1行,第一行有一個整數num,表示有num個待檢測的任務(num<=300)。接下來每行i(2<=i<=num+1)對應一個任務,每行有兩個數據,用空格分隔,第一個數據表示病毒的DNA序列(長度<=6000),第二個數據表示人的DNA序列(長度<=10000)。

        要求將檢測結果輸出到文件中,文件中包括num行,每行有三個數據,用空格分隔,前兩個數據分別表示輸入文件中對應病毒的DNA序列和人的DNA序列,如果該人感染了對應的病毒,該行第三個數據則爲“YES”,否則爲“NO”。 

        思路:我直接採用的kmp算法,這能有效改善時間複雜度。考慮到病毒基因是環狀的,所以弄了個循環來更新匹配數組的值,設置一個標記,用來判斷是否匹配。注意要將匹配串清零,以防出錯。

        注意:有些讓用BF來寫,本文不再給出代碼,可以參考代碼寫出一個BF函數即可。

#include <iostream>
#include<cstring>
#include<cstdio>
using namespace std;

char str[12005],pat[12005],pat1[12005];//pat爲模式串,str爲主串
int Next[12005]; //Next[x]下標x表示匹配失敗處字符下標
//模式串pat的前綴與x位置的後綴的最大匹配字符個數-1
void GetNext(char *pat)
{
    int LenPat = strlen(pat);
    int i = 0,j = -1;
    Next[0] = -1;
    while(i < LenPat)
    {
        if(j == -1 || pat[i] == pat[j])
        {
            i++,j++;
            Next[i] = j;
        }
        else
            j = Next[j];
    }
}

int KMP()
{
    int LenStr = strlen(str);
    int LenPat = strlen(pat);
    GetNext(pat);
    int i = 0,j = 0;
    while(i < LenStr)
    {
        if(j == -1 || str[i] == pat[j])
            i++,j++;
        else
            j = Next[j];
        if(j == LenPat)
            return 1;
    }
    return -1;//沒找到匹配位置
}
int main()
{
    int n;
    scanf("%d",&n);
    while(n--)
    {
        scanf("%s%s",pat1,str);
        char s[6005];
        memset(pat,'\0',sizeof(pat));//每次將pat數組清零
        bool flag=false;
        strcpy(s,pat1);
        int len = strlen(s);
        strcat(pat1,s);
        for(int i=0;i<=len;++i)
        {
            for(int j=0;j<len;++j)
            {
                pat[j]=pat1[i+j];
            }
            //memcpy(pat,pat1+i,len);
            if(KMP()==1)
            {
                printf("Yes\n");
                flag=true;
                break;
            }
        }
        if(!flag)
            printf("No\n");
    }
    return 0;
}

結果檢測

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章