基于kmp字符串模式配算法的病毒感染检测问题
本文记录了数据结构习题解析与实验指导(李冬梅)的实验4。
以下是实验内容
文章目录
- 1 问题描述
- 2 基本思想
- 3 KMP算法
- 4 Kmp代码主体部分
- 5 全部代码
- 6 nextval数组
1 问题描述
医学研究者最近发现了某些新病毒,通过对这些病毒的分析,得知它们的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
2 基本思想
因为是环状的,所以可以将字符串A复制一遍。然后每次取原A长度的子串。之后进行字符串匹配,这里的子串匹配算法,我所知道的有两种,一种是BF(简单,但是效率很低),另一种是KMP算法(较难理解,但效率高)。本文是利用KMP算法进行求解。
3 KMP算法
具体的思想就不讲了,讲一讲代码。
首先是求next数组的代码,(这里我的next数组是从下标0开始,第一个元素为-1的数组,另一种方法是从下标1开始存储,第一个元素为0的数组。两种方法很相似,这里介绍的是第一种方法。)
private int[] next;private String parent;private String son;public Kmp(String parent, String son) {this.parent = parent;this.son = son;next = new int[son.length()];}public void getNext() {int len = son.length();int i = -1;int j = 0;next[0] = -1;while (j < len - 1) {if (i == -1 || son.charAt(i) == son.charAt(j)) {i++;j++;next[j] = i;} else {i = next[i];}}}
基本的数据结构就不讲了,讲一讲,关键的while循环。
首先有两个下标i,j分别表示最长前缀的末尾+1和最长后缀的末尾+1.如果相等,则各自加一,这应该很好懂。放一张图解释。
(k就相当于代码中的i,j相当于代码中的j),首先看第一行红色的。如果k和j位置的元素相等,自然而然地+1,然后看下一元素是否相等。
那么如果不等怎么办呢。这时看图的第二行,首先我们可以证明黄色的部分都是相同的。那么很明显只要让k=next[k]就可以再比较了。如果相等,接着各自加1.不过这里可能你会有个疑问,为啥k要跳到next[k],才是最长的前缀呢。这里我们就要了解下next[k]的含义next[k]的含义是,k位置前的字符串最大前缀的末尾的下一个。仔细看一下图,你可能就会略懂了。而第三行蓝色的则是next[k]位置的元素和j位置的元素还不相等,那么k = next[next[k]]
的了。
最极端的时候,如果k=next[k] = -1时怎么办,那么就要再if的判断条件加上一句,关于k==-1时的判断。也就是各自都加一,也就是next[j+1]=0,然后k跳到0位置在比较。(当然这条判断也解决了初始时k==-1的问题)
最后可能会对小于len-1产生疑问。为啥不是len呢。因为我们比较的是j,但是我们实际填的是next[j+1].这里如果不懂就需要看一下手推next数组的教程了(注意这里用的是首位是-1的next数组求解方法)。
这里推荐一个视频,我觉得这个视频很好。看过之后有种恍然大悟的感觉
基于kmp字符串模式配算法的病毒感染检测问题相关推荐
- Problem C: 算法4-6:KMP字符串模式匹配算法实现
Problem Description KMP算法是字符串模式匹配算法中较为高效的算法之一,其在某次子串匹配母串失败时并未回溯母串的指针而是将子串的指针移动到相应的位置.严蔚敏老师的书中详细描述了KM ...
- KMP字符串比对算法理解
KMP算法 一种字符串比对算法,寻找存在于长字符串中的子串,由Knuth.Morris.Pratt三个同时提出来. 算法的基本思路是: 假设有序列seq(长度为m)和子序列subseq(长度为n), ...
- 算法复现 - 病毒感染检测(案例4.1算法4.5)
第1关:案例4_1 病毒感染检测 #include <iostream> #define maxsiz 20 #include<string.h> using namespac ...
- KMP字符串模式匹配算法【精简代码模板】
什么是模式匹配 模式匹配(Pattern Matching)就是在一篇长度为n的文本S中,找某个长度为m的关键字P. KMP算法如何来的? KMP算法是由朴素字符串匹配算法优化而来,就是重新利用了朴素 ...
- 基于haar特征的adaboost算法_目标检测算法介绍
什么是目标检测 目标检测是指从图像中找出目标,包括检测和识别两个过程,现实中由于环境的复杂性以及各类物体的形状.外观以及光照,遮挡等因素的干扰,所以目标检测一直也是计算机视觉最常见的挑战之一. 目标检 ...
- 光流 | 基于KLT(Kanade-Lucas-Tomasi)算法的人脸检测与跟踪
===================================================== github:https://github.com/MichaelBeechan CSDN: ...
- 数据结构——基于字符串模式匹配算法的病毒感染检测
实验四 基于字符串模式匹配算法的病毒感染检测 [实验目的] 1.掌握字符串的顺序存储表示方法. 2.掌握字符串模式匹配BF算法和KMP算法的实现. [实验内容] 问题描述 医学研究者最近发现了某些新病 ...
- 数据据结构实验4《基于字符串模式匹配算法的病毒感染检测》
(visual studio 2019可运行) 输入及输出要求见<数据结构C语言(第二版)>严蔚敏版 [本文仅用于啥都看不懂还想交作业选手] //KMP求解基于字符串模式匹配算法的病毒感染 ...
- (C语言)数据结构算法-病毒感染检测(BF算法KMP算法)
病毒感染检测: 医学研究者最近发现了某些新病毒,得知它们的DNA序列都是环状的.为了快速检测出患者是否感染了相应的病毒,研究者将患者的DNA和病毒的DNA均表示成一些字母组成的字符串序列,然后检测某种 ...
最新文章
- javascript与java正则表达式写法的区别
- C语言windows编程编写窗口
- iOS 开发问题 书籍 价值 改名 创业大赛app
- oracle11 不更新记录,oracle11g 使用first_value获取表中不连接的ID号及掉失记录数量...
- 软件工程(总体设计①设计过程)
- 图解:为什么非公平锁的性能更高?
- FPGA _Verilog HDL_计数器实现数字钟60秒计数设计实验
- Python之split()函数
- hive多个表join_8个Hive数据仓工具面试题锦集!
- centos系统盘满了 如何清理_如何拯救爆满的磁盘空间?这款 8 M小软件比 SpaceSniffer 更快更简单,支持中文。...
- SLA技术3D打印机的原理
- 深入理解Risk aversion||风险偏好||Risk utility function
- 鲁卡斯队列求黄金分割数
- 你为你的机会准备了什么
- 在中国搞自动驾驶,没有人不羡慕滴滴
- 路肩石水渠机在施工公路项目中工艺特点的匹配
- 贝叶斯例题(一)先验分布与后验分布
- Verilog 序列信号发生器的三种设计思路
- python积木编程软件_童心制物慧编程全新 Python 编辑器正式上线
- cmd下Python模块的安装
热门文章
- foxmail皮肤_Foxmail 6.5正式版 可以换肤发明信片
- 机器学习之KNN算法原理
- 你不得不了解的语义分割发展史
- 从Firechat软件追踪移动自组网技术发展
- WebLoader上传图片限制提示
- UVA10655-Contemplation! Algebra
- ill-defined and being set to 0.0 in labels with no true samples
- maya arnold AOV 自定义分层aiWritecolor使用方法
- matlab画二维正态等密度曲线,matlab:画二维正态分布密度函数图
- VS2015企业版(含安装序列号)