Welcome

首页 / 软件开发 / 数据结构与算法 / 算法系列(五)最长公共子序列(LCS)问题(非连续子序列)的两种解法

算法系列(五)最长公共子序列(LCS)问题(非连续子序列)的两种解法2014-04-30 csdn博客 吹泡泡的小猫最长公共子序列也称作最长公共子串,英文缩写是LCS(Longest Common Subsequence)。其定义 是:一个序列S,如果分别是两个或多个已知序列的子序列,且是符合此条件的子序列中最长的,则称 S为已知序列的最长公共子序列。

关于子序列的定义通常有两种方式,一种是对子序列没有连 续的要求,其子序列的定义就是原序列中删除若干元素后得到的序列。另一种是对子序列有连续的要 求,其子序列的定义是原序列中连续出现的若干个元素组成的序列。求解子序列是非连续的最长公共 子序列问题是一个十分实用的问题,它可以描述两段文字之间的“相似度”,即它们的雷同程度,从 而能够用来辨别抄袭。本文将介绍对子序列没有连续性要求的情况下如何用计算机解决最长公共子序 列问题,对子序列有连续性要求的情况下如何用计算机解决最长公共子序列问题将在后续的文章中介 绍。

一、动态规划法(Dynamic Programming)

最长公共子序列问题应该是属于多阶段 决策问题中求最优解一类的问题,凡此类问题在编制计算机程序时应优先考虑动态规划法,如果不能 用动态规划法,而且也找不到其它解决方法,还可以考虑穷举法。对于这个问题,只要能找到描述最 长公共子序列的最优子结构和最优解的堆叠方式,并且保证最优子结构中的每一次最优决策都满足“ 无后效性”,就可以考虑用动态规划法。使用动态规划法的关键是对问题进行分解,按照一定的规律 分解成子问题(分解后的子问题还可以再分解,这是个递归的过程),通过对子问题的定义找出最优 子结构中最优决策序列(对于子问题就是最有决策序列的子序列)以及最优决策序列子序列的递推关 系(当然还包括递推关系的边界值)。

如果一个给定序列的子序列是在该序列中删去若干元素 后得到的序列,也就意味着子序列在原序列中的位置索引(下标)保持严格递增的顺序。例如,序列S = <B,C,D,B>是序列K = <A,B,C,B,D,A,B>的一个子序列(非连续),序列S的元素 在在K中的位置索引I = [2,3,5,7],I是一个严格递增序列。

1.1 最优子结构定义与边界值

现在来分析一下本问题的最优子结构。首先定义问题 ,假设有字符串str1长度为m,字符串str2长度为n,可以把子问题描述为:求字符串 str1<1..m>中从第1个到第i(i <= m)个字符组成的子串str1<1…i>和字符串 str2<1..n>中从第1个到第j(j <= n)个字符组成的子串str2<1…j>的最长公共序列, 子问题的最长公共序列可以描述为d[i,j] = { Z1,Z2, … Zk },其中Z1-Zk为当前子问题已经匹配到 的最长公共子序列的字符。子问题定义以后,还要找出子问题的最优序列d[i,j]的递推关系。分析d [i,j]的递推关系要从str1[i]和str2[j]的关系入手,如果str1[i]和str2[j]相同,则d[i,j]就是d[i -1,j-1]的最长公共序列+1,Zk=str1[i]=str2[j];如果str1[i]和str2[j]不相同,则d[i,j]就是d [i-1,j]的最长公共序列和d[i,j-1]的最长公共序列中较大的那一个。

最后是确定d[i,j]的边 界值,当字符串str1为空或字符串str2为空时,其最长公共子串应该是0,也就是说当i=0或j=0时,d [i,j]就是0。d[i,j]的完整递推关系如下:

1.1 反求最长公共子序列

根据1.1得到的最 优解子结构递推关系,依次计算i从到m,j从1到n的d[i,j]值,最后得到的d[m,n]就是最长公共子序列 的长度。d[m,n]只是最长公共子序列的长度值,表示了两个字符串的相似程度,如果要获得最长公共 子序列,就需要在计算出d[m,n]矩阵的值后分析每一步决策的结果,根据每一个最优决策逆向构造出 最长公共子序列。为此需要在递推计算d[i,j]的过程中,需要同时记录下最优决策的过程,最优决策 的过程用矩阵r表示,r[i,j]表示最长公共子序列的长度值d[i,j]的“递推来源”。根据前面整理的递 推关系,如果r[i,j]的值是1,则表示d[i,j]的值由d[i-1,j-1] + 1递推得到;如果r[i,j]的值是2, 则表示d[i,j]的值由d[i-1,j]递推得到;如果r[i,j]的值是3,则表示d[i,j]的值由d[i,j-1]递推得到 。以字符串“abcdea”和“aebcda”为例,根据递推关系得到的d和r合并到一个矩阵中显示:

图(1)逆向构造最长公共子序列示意图