模式匹配(线性及环形病毒检测)

概念

模式匹配是数据结构中字符串的一种基本运算,给定一个子串,要求在主串中找出与该子串相同的所有子串,这就是模式匹配。

BF算法

BF算法即暴力(Brute Force)算法,是普通的模式匹配算法,BF算法的思想就是将目标串S的第一个字符与模式串T的第一个字符进行匹配,若相等,则继续比较S的第二个字符和 T的第二个字符;若不相等,则比较S的第二个字符和T的第一个字符,依次比较下去,直到得出最后的匹配结果。BF算法是一种蛮力算法。

线性病毒

环状病毒

依次检测病毒DNA和人的DNA是否匹配,循环执行:

l 分别读取病毒 DNA 序列和人的 DNA 序列;
l 设置 flag ,初始为 0 ,表示未匹配;
l 病毒 DNA 长度是 m ,连续存储两次扩大为 2m
l 循环 m 次,重复执行以下操作:
Ø 依次取得每个长度为 m 的病毒 DNA 环状字符串;
Ø 将此字符串作模式串,将人的 DNA 作主串,调用 BF ,将结果返回 flag
Ø flag 0 ,表示匹配成功。
l 退出循环时,若 flag 0 ,输出“ YES ”,否则,输出“ NO ”。

废话不多说直接上代码,我称它为BFPro算法

#include<string.h>  /*是在程序编译之前要处理的内容,与字符串的调用有关,常用函数包括strlen(求字符串长度)、strcmp(比较两个字符串是否一样)和strcat(字符串连结操作)等*/
#include<stdio.h>


#define OK 1
#define ERROR 0
#define OVERFLOW -2
#define MAXSTRLEN 255   		//用户可在255以内定义最长串长
typedef char SString[MAXSTRLEN+1];	//0号单元存放串的长度
//初始化字符数组
int StrAssign(SString T,char *chars){
	size_t i;
	if(strlen(chars)>MAXSTRLEN){
		return ERROR;
	}else{
		T[0] = strlen(chars); // 将字符串长度存储在 T[0] 中  
		for (i=1; i < strlen(chars)+1; i++) { // 在循环中复制每个字符  
		
		    T[i] = *(chars + i - 1);   
		}  
		T[i] = '\0'; // 在字符串末尾添加空字符  
		return OK; // 返回操作成功  
	}
}
//BF算法
int BF(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;
	}
}

//复制子串
//需要两个参数,一个是复制的字符数组,另一个是字符串变量的长度
void CopyNewArray(SString T,int length) {  
	//创建一个临时数组,用来存储当前的字符串
    char temp[length];
    //将要复制的字符数组长度变为2倍加1,因为数组第0位存储长度
	T[0] = length*2+1;
	//将字符数组复制给temp临时字符数组
    for (int i = 0; i <=length; i++) {  
        temp[i] = T[i+1];  
    }
    //将temp数组中的元素添加到复制的字符数组中
    for (int i = length+1; i <=2 * length+1; i++) {  
        T[i] = temp[i -length-1];  
    }  
} 
//模式匹配环状病毒,BFPro,传入三个参数,主串,病毒串,病毒串长度
//病毒长度用于计量一次取出多少个元素
int BFPro(SString S,SString T,int length){
		//flag标志位
	 	int flag=0;
	 	//temp临时数组,存储每次需要比较的字符,长度为length,temp[0]存储长度
 		char temp[length]={length};
 		//定义一个索引下标,只来指向T数组的字符下标,初始下标为1,因为T[0]存储的是长度
	 	int index = 1;
		//循环取出需要需要比较的字串,并调用BF算法进行比较
		//循环终止条件是索引下标于T数组的长度
		while (index <= length * 2) {
			// 从数组T中取出m个元素给temp
	        for (int i = 1; i <length+1; i++) { 
	        	//先取出第一个,后将索引下标自增
	            temp[i] = T[index++]; 
	        }
	        //输出temp数组中存储的元素
			printf("目标子串为:"); 
	        for(int i=1;i<length+1;i++){
				printf("%c",temp[i]);
			}
	        printf("\n");
	        //判断是否取到了T数组的最后一位
			//如果没取到最后一位就将索引下标后移一位,重新取出length个元素,以便于循环继续
	        if(index<=length*2){
				index=index-length+1;  
			}
			//调用BF算法,将temp数组与主串进行比较,返回值赋给flag
			flag=BF(S,temp,1);
			//判读返回值是否为0,不为零即找在主串中找到了字串,返回flag子串在主串中出现的位置
			if(flag!=0){
				return flag;
			}
	    }
	    //如果循环结束后还没有返回flag,就表示子串没有出现在主串中,返回0 
	    return flag;
}

int main()
{
	int i;
	SString S,T;
	StrAssign(S,"bcaCaebbpaba") ;
	StrAssign(T,"bcb");
	int length=T[0];
	printf("主串是:");
	for (i = 1; i <= S[0]; i++){
		printf("%c",S[i]);
	}
	printf("\n");
	printf("子串是:");
	for (i = 1; i <= T[0]; i++){
		printf("%c",T[i]);
		}
	printf("\n\n");
	//调用CopyNewArray方法复制子串
	CopyNewArray(T, length);  
	printf("新的子串是:");
	//输出复制后的子串
	for (i = 1; i <= T[0]; i++){
		printf("%c",T[i]);
		}
	printf("\n\n");
	//调用BFPro方法进行比较,将返回值赋值给flag
	int flag=BFPro(S,T,length);
	//判断flag的值,如果不为0,表示子串出现在主串中,患者感染,感染位为flag
	//否则未感染
	if(flag){
		printf("该患者已感染病毒。主串(患者DNA)和子串(病毒DNA)在第%d个字符处首次匹配",flag);		
	}else{
		printf("患者未感染病毒!");
	}
}

运行图如下

  • 6
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值