实验一 -3 利用串的各种模式匹配算法实现病毒感染检测

本文详细介绍了如何利用顺序串和KMP算法进行病毒感染检测,包括实验目的、数据预处理、朴素模式匹配和KMP算法的实现过程,以及对算法性能的分析和结果对比。
摘要由CSDN通过智能技术生成

利用串的各种模式匹配算法实现病毒感染检测

目录

利用串的各种模式匹配算法实现病毒感染检测

一、实验目的

二、实验内容

三、实验设备与环境

四、实验设计方案

五、实验结果

 六、附录


一、实验目的

1.了解串的基本概念和操作。
2.掌握顺序串的实现方法。
3.掌握串的模式匹配算法
4.利用顺序串实现病毒感染检测

二、实验内容

 利用顺序串实现串的各种模式匹配算法。研究者将人的DNA和病毒DNA均表示成由一些字母组成的字符串序列。然后检测某种病毒DNA序列是否在患者的DNA序列中出现过,如果出现过,则此人感染了该病毒,否则没有感染。例如,假设病毒的DNA序列为t=“baa”,患者1的DNA序列为s1=“aaabbaaba”,则感染,患者2的DNA序列为s2=“babbbabcabb”,则未感染。请你编写实现病毒感染检测。

三、实验设备与环境

1.Windows11

2.Codeblocks

四、实验设计方案

实验步骤:

1.数据预处理:

(1)读取病毒DNA序列和患者DNA序列。
(2)去除输入字符串中的空格和其他非字母字符。
(3)将所有字符串转换为小写字母。
2.朴素模式匹配算法实现:

(1)定义函数,其中s是患者的DNA序列,p是病毒的DNA序列。
(2)使用两个指针i和j分别指向字符串s和p的起始位置。
(3)循环遍历字符串s和p,比较对应位置的字符是否相等。如果相等,则将指针j后移一位;否则,将指针i后移一位。
(4)如果指针j到达字符串p的末尾,说明字符串p在字符串s中出现了,返回True;否则返回False。
3.KMP算法实现:

(1)定义函数kmp_match(s, p),其中s是患者的DNA序列,p是病毒的DNA序列。
(2)创建一个辅助数组(或称为“部分匹配表”)来存储字符串p的部分匹配信息。
(3)使用两个指针i和j分别指向字符串s和p的起始位置。
(4)循环遍历字符串s和p,比较对应位置的字符是否相等。如果相等,则将指针j后移一位;否则,根据部分匹配表的信息移动指针i。
(5)如果指针j到达字符串p的末尾,说明字符串p在字符串s中出现了,返回True;否则返回False。
4.病毒感染检测:

(1)对于每组病毒DNA序列和患者DNA序列,调用朴素模式匹配算法和KMP算法进行匹配。
(2)比较两种算法的执行时间和结果,输出患者是否感染该病毒。
5.结果分析:

(1)分析实验结果,包括不同算法的时间复杂度和空间复杂度,以及在实际数据上的表现。
(2)编写完整的程序文档,包括算法描述、数据结构、输入输出格式等。

设计思想与算法描述

1.设计思想:

本实验旨在通过实现两种常见的模式匹配算法(朴素模式匹配算法和KMP算法)来检测病毒感染。通过比较两种算法的性能,我们可以更好地理解它们在实际问题中的应用。在实现算法时,需要注意时间复杂度和空间复杂度的控制,以提高程序的效率。此外,考虑到DNA序列的特点,我们需要选择适合的字符串匹配算法来确保程序的正确性和效率。
2.算法描述:
朴素模式匹配算法:该算法通过逐个比较字符串中的字符来确定模式是否出现。它的时间复杂度为O(n*m),其中n是主字符串的长度,m是模式字符串的长度。空间复杂度为O(1)。具体实现时,可以使用双指针技术进行字符比较和位置移动。
KMP算法:该算法通过利用已经匹配的信息来优化匹配过程。它的时间复杂度为O(n+m),其中n是主字符串的长度,m是模式字符串的长度。空间复杂度为O(m)。具体实现时,需要创建一个部分匹配表来存储模式字符串的部分匹配信息。在匹配过程中,根据部分匹配表的信息进行指针移动,以提高匹配效率。
3.开发流程:

首先进行数据预处理,包括去除空格和非字母字符、转换为小写字母等操作。然后分别实现朴素模式匹配算法和KMP算法,并编写病毒感染检测程序。在实现过程中,需要注意代码的可读性和可维护性,同时进行必要的错误处理和边界检查。最后进行测试与验证,选择多组病毒DNA序列和患者DNA序列作为测试数据,比较两种算法的执行时间和结果,验证程序的正确性和效率。同时分析实验结果,编写完整的程序文档。

五、实验结果

 六、附录

#include <stdio.h>
#include <string.h>

#define MaxSize 100

typedef struct
{
    char data[MaxSize];                                    // 定义可容纳MaxSize个字符的空间
    int length;                                            // 标记当前实际串长
}SqString;

/*---------------------------简单匹配算法-------------------------------*/
int Index(SqString s, SqString t)
{
    int i = 0;
    int j = 0;
    int k;

    while((i < s.length) && (j < t.length))
    {
        if(s.data[i] == t.data[j])                            // 继续匹配下一个字符
        {
            i++;
            j++;
        }
        else                                                // 主串/子串指针回溯重新开始下一次匹配
        {
            i = i - j + 1;
            j = 0;
        }
    }

    if(j >= t.length)                                        // 返回匹配的第一个字符的下标
        k = i - t.length;
    else                                                    // 模式匹配不成功
        k = -1;

    return k;
}

/*-----------------------------由模式串t求出next值-------------------------------*/
void GetNext(SqString t, int next[])
{
    int j;
    int k;

    j = 0;
    k = -1;
    next[0] = -1;
    while(j < t.length - 1)
    {
        if((k == -1) || (t.data[j] == t.data[k]))
        {
            j++;
            k++;
            next[j] = k;
        }
        else
        {
            k = next[k];
        }
    }
}

/*-----------------------------由模式串t求出nextval值-------------------------------*/
void GetNextval(SqString t, int nextval[])
{
    int j;
    int k;

    j = 0;
    k = -1;
    nextval[0] = -1;
    while(j < t.length)
    {
        if((k == -1) || (t.data[j] == t.data[k]))
        {
            j++;
            k++;
            if(t.data[j] != t.data[k])
                nextval[j] = k;
            else
                nextval[j] = nextval[k];
        }
        else
        {
            k = nextval[k];
        }
    }
}

int KMPIndex(SqString s, SqString t)
{
    int next[MaxSize];
    int i = 0;
    int j = 0;
    int v;

    GetNext(t, next);
    while((i < s.length) && (j < t.length))
    {
        if((j == -1) || (s.data[i] == t.data[j]))
        {
            i++;
            j++;                                // i,j各增1
        }
        else
            j = next[j];                        // i不变,j后退
    }
    if(j >= t.length)
        v = i - t.length;                        // 返回匹配模式串的首字符下标
    else
        v = -1;                                    // 返回不匹配标志

    return v;
}

int KMPIndex1(SqString s, SqString t)
{
    int nextval[MaxSize];
    int next[MaxSize];
    int i = 0;
    int j = 0;
    int v;

    GetNextval(t, next);
    GetNextval(t, nextval);
    while((i < s.length) && (j < t.length))
    {
        if((j == -1) || (s.data[i] == t.data[j]))
        {
            i++;
            j++;                                // i,j各增1
        }
        else
            j = nextval[j];
    }
    if(j >= t.length)
        v = i - t.length;                        // 返回匹配模式串的首字符下标
    else
        v = -1;                                    // 返回不匹配标志

    return v;
}

/*---------------------------由串常量cstr创建串str-------------------------------*/
void StrAssign(SqString &str, char cstr[])
{
    int i;

    for(i = 0; cstr[i] != '\0'; i++)
        str.data[i] = cstr[i];
    str.length = i;
}

/*---------------------------输出串s的所有元素-------------------------------*/
void DispStr(SqString s)
{
    int i;

    if(s.length > 0)
    {
        for(i = 0; i < s.length; i++)
            printf("%c", s.data[i]);
        printf("\n");
    }
}

int main(void)
{
    int j;
    int next[MaxSize], nextval[MaxSize];
    SqString s, t;

    StrAssign(s, " aaabbaaba ");
    StrAssign(t, " babbbabcabb ");
    printf("串s:");
    DispStr(s);
    printf("串t:");
    DispStr(t);
    printf("简单匹配算法:\n");
    printf("  t在s中的位置=%d\n", Index(s, t));
    GetNext(t, next);                                        // 由模式串t求出next值
    GetNextval(t, nextval);                                    // 由模式串t求出nextval值

    printf("    j    ");
    for(j = 0; j < t.length; j++)
        printf("%4d", j);
    printf("\n");
    printf(" t[j]    ");
    for(j = 0; j < t.length; j++)
        printf("%4c", t.data[j]);
    printf("\n");
    printf(" next    ");
    for(j = 0; j < t.length; j++)
        printf("%4d", next[j]);
    printf("\n");
    printf(" nextval ");
    for(j = 0; j < t.length; j++)
        printf("%4d", nextval[j]);
    printf("\n");
    printf("KMP算法:\n");
    printf("  t在s中的位置=%d\n", KMPIndex(s, t));
    printf("改进的KMP算法:\n");
    printf("  t在s中的位置=%d\n", KMPIndex1(s, t));

    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

噗-噗

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值