实验三 基于字符串模式匹配算法的病毒 感染检测问题

实验三 基于字符串模式匹配算法的病毒感染检测问题
一、实验目的
1、掌握字符串的顺序存储表示方法。
2、掌握字符串模式匹配算法 BF 算法或 KMP 算法的实现。
二.实验内容
医学研究者最近发现了某些新病毒,通过对这些病毒的分析,得知它们的
DNA 序列都是环状的。现在研究者已收集了大量的病毒 DNA 和人的 DNA 数据,
想快速检测出这些人是否感染了相应的病毒。为了方便研究,研究者将人的 DNA
和病毒 DNA 均表示成由一些字母组成的字符串序列,然后检测某种病毒 DNA
序列是否在患者的 DNA 序列中出现过,如果出现过,则此人感染了该病毒,否
则没有感染。
三、实验实习设备及开发环境
Visual studio 2022
四.实验实习过程步骤(注意是主要关键步骤,不是所有步骤,适当文字+截图说明)
Function1:将病毒的字符串复制一次。创建了一个字符串来暂时存储复制后的字符串,然后将此字符串指针再赋值给原来的病毒的字符串
在这里插入图片描述

Function2:初始化字符串,创建字符串。
在这里插入图片描述

Function3:利用bf算法,一位一位进行匹配,如果模式串已经匹配成功了,就直接返回位置,如果匹配到某个位置就失败了,就将模式串进行回溯,回到之前的点,然后主串回到下一个字符位置。如果提前找到,直接退出,如果没找到,就循环完,返回0。
在这里插入图片描述
在这里插入图片描述

Function4:主函数,用的文件读取,先打开文件,读取文件里面的字符串然后先复制病毒串,然后利用bf算法,然后将结果如果是0就是NO,1是YES。
在这里插入图片描述
在这里插入图片描述

五、实验实习结果及分析
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

六、实验遇到的问题及解决办法,实验心得体会及对此实验的意见或建议(有就写,无可不写)。
因为使用的是通过读取文件的操作来进行读取数据的,在读取每一行的时候,会多读取一个/n,并且在使用strlen()函数的时候会把\n也读取进去,所以在复制字符串,以及使用他们的长度的时候都需要注意一下,本人被这个调试了很久。

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAX 1024
#define OK 1
#define ERROR 0

typedef int Status;

typedef struct Hstring
{
	char* str;
	int maxlength;
}Hstring;

//让字符串喜欢一次,来代表循环字符串
Status copyHstring(Hstring* S,int length2)
{
    Hstring temp;
    Init(&temp);

    if (!temp.str)
    {
        printf("内存分配失败\n");
        return ERROR;
    }

    int j = 0;
    int i = 0;

    while (j < length2-1&&i<2*(length2 -1))
    {
        temp.str[i] = S->str[j];
        i++;
        j++;
        if (j ==(length2)-1)
        {
            j = 0;
        }
    }

    temp.str[i] = '\0';

    free(S->str); // Free the old buffer
    S->str = temp.str;//te the pointer to the new buffer

    return OK;
}

Status Init(Hstring* S)
{
	S->str = malloc(sizeof(char) * MAX);
	if (!S->str)
	{
		printf("创建数组失败\n");
		return ERROR;
	}
	S->maxlength = MAX;
	return OK;

}

int bf_cal(Hstring* mode, Hstring* main,int length2)
{
	int i = 0, j = 0;
    int length_mode = length2 - 1;
    int length_main = strlen(main->str) - 1;
    int k = 0;
    Hstring temp;
    Init(&temp);
    int q = 0;
    int p = 0;
    for (p = 0; p < length_mode; p++)
    {
        i = 0;
        j = 0;
        q = 0;
        for (k = p; k < length_mode + p; k++)
        {
            temp.str[q] = mode->str[k];
            q++;
        }
        temp.str[q] = '\0';
        while (i < length_mode && j < length_main)
        {
            if (temp.str[i]==main->str[j])
            {
                j++;
                i++;
            }
            else
            {
                j = j - i + 1;
                i = 0;
            }

        }
        if (i >= length_mode)
        {
            return j - length_mode + 1;
        }
    }
    
    return 0;
}


int main()
{
    Hstring str1, str2;
    Init(&str1);
    Init(&str2);
    FILE* p1, * p2;

    p1 = fopen("F:\\c code\\people.txt", "r");
    if (!p1) {
        printf("Error opening file: people.txt\n");

    }

   

    p2 = fopen("F:\\c code\\virus.txt", "r");
    if (!p2) {
        printf("Error opening file: virus.txt\n");
        fclose(p1);

    }


    while (fgets(str2.str, MAX, p2) != NULL&&fgets(str1.str,MAX,p1)!=NULL)
    {
        int length2 = strlen(str2.str);
        copyHstring(&str2, length2);
        int res;
        res = bf_cal(&str2, &str1, length2);
        if (res == 0)
        {
            printf("NO\n");
        }
        else
        {
            printf("YES\n");
        }
    }


    fclose(p1);
    fclose(p2);

    return 0;
}
  • 14
    点赞
  • 23
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
BF算法和KMP算法都是串的模式匹配算法,但是它们的时间复杂度不同。BF算法的时间复杂度为O(m*n),其中m和n分别为主串和模式串的长度。而KMP算法的时间复杂度为O(m+n)。因此,当模式串较长时,KMP算法的效率更高。 下面是BF算法和KMP算法的介绍和演示: 1. BF算法(暴力匹配算法) BF算法是一种朴素的模式匹配算法,它的思想是从主串的第一个字符开始,依次和模式串的每个字符进行比较,如果匹配成功,则继续比较下一个字符,否则从主串的下一个字符开始重新匹配。BF算法的时间复杂度为O(m*n)。 下面是BF算法的Python代码演示: ```python def BF(main_str, pattern_str): m = len(main_str) n = len(pattern_str) for i in range(m-n+1): j = 0 while j < n and main_str[i+j] == pattern_str[j]: j += 1 if j == n: return i return -1 # 测试 main_str = 'ababcabcacbab' pattern_str = 'abcac' print(BF(main_str, pattern_str)) # 输出:6 ``` 2. KMP算法(Knuth-Morris-Pratt算法) KMP算法是一种改进的模式匹配算法,它的核心思想是利用已经匹配过的信息,尽量减少模式串与主串的匹配次数。具体来说,KMP算法通过预处理模式串,得到一个next数组,用于指导匹配过程中的跳转。KMP算法的时间复杂度为O(m+n)。 下面是KMP算法的Python代码演示: ```python def KMP(main_str, pattern_str): m = len(main_str) n = len(pattern_str) next = getNext(pattern_str) i = 0 j = 0 while i < m and j < n: if j == -1 or main_str[i] == pattern_str[j]: i += 1 j += 1 else: j = next[j] if j == n: return i - j else: return -1 def getNext(pattern_str): n = len(pattern_str) next = [-1] * n i = 0 j = -1 while i < n-1: if j == -1 or pattern_str[i] == pattern_str[j]: i += 1 j += 1 next[i] = j else: j = next[j] return next # 测试 main_str = 'ababcabcacbab' pattern_str = 'abcac' print(KMP(main_str, pattern_str)) # 输出:6 ```

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值