基于字符串模式匹配算法的病毒感染检测(bf和kmp)

写在前边:这是一个菜鸡的19年秋季学期数据结构实验课,趁寒假整理一下,欢迎各位大佬指正)

基于字符串模式匹配算法的病毒感染检测

【实验目的】
1.掌握字符串的顺序存储表示方法。
2.掌握字符串模式匹配BF算法和KMP算法的实现。
【实验内容】
问题描述
医学研究者最近发现了某些新病毒,通过对这些病毒的分析,得知它们的DNA序列都是环状的。现在研究者已收集了大量的病毒DNA和人的DNA数据,想快速检测出这些人是否感染了相应的病毒。为了方便研究,研究者将人的DNA和病毒DNA均表示成由一些字母组成的字符序列,然后检测某种病毒DNA序列是否在患者的DNA序列中出现过。如果出现过,则此人感染了该病毒,否则没有感染。例如,假设病毒的DNA序列为baa,患者1的DNA序列为aaabbba,则感染;患者2的DNA序列为babbba,则未感染。(注意,人的DNA序列是线性的,而病毒的DNA序列是环状的。)
输入要求
多组数据,每组数据一行,对应一个算术表达式,每个表达式均以“=”结尾。当表达式只有一个“=”时,输入结東。
输出要求
多组数据,每组数据有1行,为序列A和B,A对应病毒的DNA序列,B对应人的DNA序列。A和B都为“0”时输入结束。
输入样例
abbab abbabaab
baa cacdvcabacsd
abc def
0 0
输出样例
YES
YES
NO
【实验提示】
此实验内容即要求实现教材算法的具体案例。利用BF算法来实现字符串的模式匹配过程的,效率较低,。利用KMP算法完成模式匹配以提高算法的效率。

BF算法如下
代码原理:

  1. 利用BF算法进行比对
  2. 因为子串为环形,需要改变子串进行比对;
    char temp= a[0];
    for(int k=0;k {
    a[k]=a[k+1];
    }
    a[pl-1]=temp;
    不足之处:
    忽略了strlen(str)不等于数组的最后标号,浪费了大量时间
#include 
#include
#include
using namespace std;
int sl,pl;
bf(char *s,char *p)
{
	int flag=0;

	int i=0,j=0,t=0;
	while(i<sl && j<pl)
	{
	
		if(s[i]==p[j])
		{
			if(j==pl-1)
			{
				flag=1;
				break;
			}
			i++;
			j++;
		          
		}
		else
		{
			i=++t;
			j=0;
		}
	}
	
	
		return flag;
}


int main()
{
	
	int i=0;
	char a[50],b[50];
	char temp;
	while(1)
	{
	
	    scanf("%s %s",a,b);
		if(a[0]=='0'&&a[1]=='\0'&&b[0]=='0'&&b[1]=='\0')
		break;
		else{
		pl=strlen(a);//子串长 
		sl=strlen(b);//主串长 
	 
		for(i=0;i<pl;i++)
		{
			
	        if(bf(b,a))
			{
		
			cout<<"yes"<<endl;
			break;
	     	}
			else {
		
			char temp= a[0];
			for(int k=0;k<pl-1;k++)
			{
			   a[k]=a[k+1];
			}
			a[pl-1]=temp;

		}
		if(i==pl)
		cout<<"no"<<endl;
	}
	
	}
}
	
}

KMP算法如下
关键是得到nextval数组,代码如下
while(t {
int j=0;
if(j==0||a[t]==a[j])
{
++t;
++j;
if(a[t]!=a[j])
next[t]=j;
else
next[t]=next[j];
}
else
j=next[j];
}

#include 
#include
#include
using namespace std;
int sl,pl;
int next[30];
int KMP(char *s,char *p)
{
	int flag=0;

	int i=0,j=0,t=0;
	while(i<sl && j<pl)
	{
	
		if(j==0||s[i]==p[j])
		{
		   if(j==pl-1)
			{
				flag=1;
				break;
			}
			i++;
			j++; 
		}
		else
		{
			j=next[j];

		}
	}
	
	
		return flag;

	
}


int main()
{
	
	int i=0,t=0;
	char a[50],b[50];
	char temp;
	 next[0] = 0;  
    
	while(1)
	{
	
	    scanf("%s %s",a,b);
		if(a[0]=='0'&&a[1]=='\0'&&b[0]=='0'&&b[1]=='\0')
		break;
		else{
		pl=strlen(a);//子串长 
		sl=strlen(b);//主串长 
	   while(t<pl)//得到nrxtval数组 
     {
	        int j=0;
         if(j==0||a[t]==a[j])
         {
             ++t;
             ++j;
             if(a[t]!=a[j])
                 next[t]=j;
             else
                 next[t]=next[j];
         }         
		 else
           j=next[j];
    }  
		for(i=0;i<pl;i++)
		{
			
	        if(KMP(b,a))
			{
			cout<<"yes"<<endl;
			break;
	     	}
			else {
		
			char temp= a[0];
			for(int k=0;k<pl-1;k++)
			{
			   a[k]=a[k+1];
			}
			a[pl-1]=temp;
		       	}
		}
		if(i==pl)
		cout<<"no"<<endl;
	}
	
	}
	
}

你可能感兴趣的:(基于字符串模式匹配算法的病毒感染检测(bf和kmp))