算法系列(六)最长公共子序列(LCS)问题(连续子序列)的三种解法

最长公共子序列(LCS)问题有两种方式定义子序列,一种是子序列不要求不连续,一种是子序列 必须连续。上一章介绍了用两种算法解决子序列不要求连续的最终公共子序列问题,本章将介绍要求 子序列必须是连续的情况下如何用算法解决最长公共子序列问题。

仍以上一章的两个字符串 “abcdea”和“aebcda”为例,如果子序列不要求连续,其最长公共子序列为“abcda”,如果子序列 要求是连续,则其最长公共子序列应为“bcd”。在这种情况下,有可能两个字符串出现多个长度相同 的公共子串,比如“askdfiryetd”和“trkdffirey”两个字符串就存在两个长度为3的公共子串,分 别是“kdf”和“fir”,因此问题的性质发生了变化,需要找出两个字符串所有可能存在公共子串的 情况,然后取最长的一个,如果有多个最长的公共子串,只取其中一个即可。

字符串 “abcdea”和“aebcda”如果都以最左端的a字符对齐,则能够匹配的最长公共子串就是“a”。但是 如果用第二个字符串的e字符对齐第一个字符串的a字符,则能够匹配的最长公共子串就是“bcd”。可 见,从两个字符串的不同位置开始对齐匹配,可以得到不同的结果,因此,本文采用的算法就是穷举 两个字符串所有可能的对齐方式,对每种对齐方式进行字符的逐个匹配,找出最长的匹配子串。

一、递归方法

首先看看递归方法。递归的方法比较简单,就是比较两个字符串的首 字符是否相等,如果相等则将其添加到已知的公共子串结尾,然后对两个字符串去掉首字符后剩下的 子串继续递归匹配。如果两个字符串的首字符不相等,则用三种对齐策略分别计算可能的最长公共子 串,然后取最长的一个与当前已知的最长公共子串比较,如果比当前已知的最长公共子串长就用计算 出的最长公共子串代替当前已知的最长公共子串。第一种策略是将第一个字符串的首字符删除,将剩 下的子串与第二个字符串继续匹配;第二种策略是将第二个字符串的首字符删除,将剩下的子串与第 一个字符串继续匹配;第三种策略是将两个字符串的首字符都删除,然后继续匹配两个字符串剩下的 子串。删除首字符相当于字符对齐移位,整个算法实现如下:

180 void RecursionLCS

(const std::string& str1, const std::string& str2, std::string& lcs)   

181 {   

182     if(str1.length() == 0 || str2.length() == 0)   

183         return;   

184    

185     if(str1[0] == str2[0])   

186     {   

187         lcs += str1[0];   

188         RecursionLCS(str1.substr(1), str2.substr(1), lcs);   

189     }   

190     else

191     {   

192         std::string strTmp1,strTmp2,strTmp3;   

193    

194         RecursionLCS(str1.substr(1), str2, strTmp1);   

195         RecursionLCS(str1, str2.substr(1), strTmp2);   

196         RecursionLCS(str1.substr(1), str2.substr(1), strTmp3);   

197         std::string strLongest = GetLongestString(strTmp1, strTmp2, strTmp3);   

198         if(lcs.length() < strLongest.length())   

199             lcs = strLongest;   

200     }   

201 }

以上是小编为您精心准备的的内容,在的博客、问答、公众号、人物、课程等栏目也有的相关内容,欢迎继续使用右上角搜索按钮进行搜索递归
, 字符串
, 大量连续序列数据
, 序列
, 两个
, 数据库 连续字符
, 最长公共子序列
, 所有公共子序列
, 公共子序列
, 子匹配
, 子串
, 最长公共子串
, 最长
公共
lcs最长公共子序列、lcs算法最长公共子串、一个极值的三种解法、圆的最值问题三种解法、鲁班锁6根 三种解法,以便于您获取更多的相关知识。

时间: 2024-10-31 17:19:34

算法系列(六)最长公共子序列(LCS)问题(连续子序列)的三种解法的相关文章

文本比较算法Ⅶ——线性空间求最长公共子序列的Nakatsu算法

在参阅<A Longest Common Subsequence Algorithm Suitable for Similar Text Strings>(Narao Nakatsu,Yahiko Kambayashi,Shuzo Yajima著)后.发现该算法可以利用线性空间求出最长公共子序列.该算法的时间占用O(n(m-p+1)),p为最长公共子序列的长度.   字符串A和字符串B,计算LCS(A,B) 定义一:设M=Len(A),N=Len(B),不妨设M≤N. 定义二:A=a1a2--

算法知识之最长公共子序列问题(动态规划)

最近朋友让帮做个关于动态规划的最长公共子序列的问题,翻看以前的笔记并完成该题后,顺便写这样一篇文章,希望对大家有所帮助,同时也帮助自己回顾该知识点. 一.最长公共子序列的定义 子序列:若给定序列X={x1,x2,-,xm},则另一序列Z={z1,z2,-,zk},是X的子序列是指存在一个严格递增下标序列{i1,i2,-,ik}使得对于所有j=1,2,-,k有:zj=xij.公共子序列:给定2个序列X和Y,当另一序列Z既是X的子序列又是Y的子序列时,称Z是序列X和Y的公共子序列.最长公共子序列:给

【字符串处理算法】获取最长公共子串的算法设计及C代码实现

一.需求描述 输入两个字符串,编写程序获取这两个字符串的第一个最长公共子串. 例如,输入的字符串为"abcdef"和"fecdba",那么这两个字符串的第一个最长公共子串为"cd".   二.算法设计 我们可以首先寻找两个字符串中的第一个相等的字符,然后分别向后移动来比较对应位置的字符是否相等. 即如果字符串1为"1234abcd",字符串2为"abd",那么首先发现字符串1中的第五个字符"a&q

[算法系列之三十一]最近公共祖先(LCA)

[简介] 对于有根树T的两个结点u.v,最近公共祖先LCA(T,u,v)表示一个结点x,满足x是u.v的祖先且x的深度尽可能大. 另一种理解方式是把T理解为一个无向无环图,而LCA(T,u,v)即u到v的最短路上深度最小的点. 例如,对于下面的树,结点4和结点6的最近公共祖先LCA(T,4,6)为结点2. 求树中两个结点的最低公共祖先是面试中经常出现的一个问题.一般的做法,可能是针对是否为二叉查找树分情况讨论. LCA问题的扩展主要在于结点是否只包含父结点指针,对于同一棵树是否进行多次LCA查询

NYOJ&amp;#160;36&amp;#160;LCS&amp;#160;最长公共子序列

最长公共子序列 时间限制:3000 ms  |  内存限制:65535 KB 难度:3 描述 咱们就不拐弯抹角了,如题,需要你做的就是写一个程序,得出最长公共子序列. tip:最长公共子序列也称作最长公共子串(不要求连续),英文缩写为LCS(Longest Common Subsequence).其定义是,一个序列 S ,如果分别是两个或多个已知序列的子序列,且是所有符合此条件序列中最长的,则 S 称为已知序列的最长公共子序列. 输入 第一行给出一个整数N(0 接下来每组数据两行,分别为待测的两

利用C++实现最长公共子序列与最长公共子串_C 语言

一.问题描述 子串应该比较好理解,至于什么是子序列,这里给出一个例子:有两个母串 cnblogs belong 比如序列bo, bg, lg在母串cnblogs与belong中都出现过并且出现顺序与母串保持一致,我们将其称为公共子序列.最长公共子序列(Longest Common Subsequence, LCS),顾名思义,是指在所有的子序列中最长的那一个.子串是要求更严格的一种子序列,要求在母串中连续地出现.在上述例子的中,最长公共子序列为blog(cnblogs, belong),最长公共

NYOJ36-最长公共子序列

最长公共子序列 时间限制:3000 ms  |  内存限制:65535 KB 难度:3 描述 咱们就不拐弯抹角了,如题,需要你做的就是写一个程序,得出最长公共子序列. tip:最长公共子序列也称作最长公共子串(不要求连续),英文缩写为LCS(Longest Common Subsequence).其定义是,一个序列 S ,如果分别是两个或多个已知序列的子序列,且是所有符合此条件序列中最长的,则 S 称为已知序列的最长公共子序列. 输入 第一行给出一个整数N(0<N<100)表示待测数据组数 接

九度题目1011:最大连续子序列

题目1011:最大连续子序列 时间限制:1 秒 内存限制:32 兆 特殊判题:否 提交:4263 解决:2063 题目描述:     给定K个整数的序列{ N1, N2, ..., NK },其任意连续子序列可表示为{ Ni, Ni+1, ..., Nj },其中 1 <= i <= j <= K.最大连续子序列是所有连续子序列中元素和最大的一个,例如给定序列{ -2, 11, -4, 13, -5, -2 },其最大连续子序列为{ 11, -4, 13 },最大和为20.现在增加一个要

HDU1231最大连续子序列

最大连续子序列 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 16639    Accepted Submission(s): 7294 Problem Description 给定K个整数的序列{ N1, N2, ..., NK },其任意连续子序列可表示为{ Ni, Ni+1, ...,  Nj },其中 1 <= i <= j