您现在的位置是:首页 > 文章详情

最长公共子序列(LCS)

日期:2019-06-10点击:494

问题描述

子串应该比较好理解,至于什么是子序列,这里给出一个例子:有两个母串

  • cnblogs
  • belong

比如序列bo, bg, lg在母串cnblogs与belong中都出现过并且出现顺序与母串保持一致,我们将其称为公共子序列。最长公共子序列(Longest Common Subsequence,LCS),顾名思义,是指在所有的子序列中最长的那一个。子串是要求更严格的一种子序列,要求在母串中连续地出现。在上述例子的中,最长公共子序列为blog(cnblogs,belong),最长公共子串为lo(cnblogs, belong)。

求解算法

对于母串X=, Y=,求LCS与最长公共子串。
假设Z=是X与Y的LCS, 我们观察到:

  • 如果Xm=Yn,则Zk=Xm=Yn,有:Zk−1是Xm−1与Yn−1的LCS;
  • 如果Xm≠Yn,则Zk是Xm与Yn−1的LCS,或者是Xm−1与Yn的LCS。

因此,求解LCS的问题则变成递归求解的两个子问题。但是,上述的递归求解的办法中,重复的子问题多,效率低下。改进的办法——用空间换时间,用数组保存中间状态,方便后面的计算。这就是动态规划(DP)的核心思想了。
DP求解LCS
用二维数组ci记录串x1,x2,⋯,xi与y1,y2,⋯,yj的LCS长度,则可得到状态转移方程:
20161116110820862
由最长公共子序列问题的最优子结构性质可知,要找出X=和Y=的最长公共子序列,可按以下方式递归地进行:当xm=yn时,找出Xm-1和Yn-1的最长公共子序列,然后在其尾部加上xm(=yn)即可得X和Y的一个最长公共子序列。当xm≠yn时,必须解两个子问题,即找出Xm-1和Y的一个最长公共子序列及X和Yn-1的一个最长公共子序列。这两个公共子序列中较长者即为X和Y的一个最长公共子序列。
在算法LCS中,每一次的递归调用使i或j减1,因此算法的计算时间为O(m+n)

代码实现

int lcs(String str1, String str2) { int len1 = str1.length(); int len2 = str2.length(); int c[][] = new int[len1 + 1][len2 + 1]; for (int i = 0; i <= len1; i++) { for (int j = 0; j <= len2; j++) { if (i == 0 || j == 0) { c[i][j] = 0; } else if (str1.charAt(i - 1) == str2.charAt(j - 1)) { c[i][j] = c[i - 1][j - 1] + 1; } else { c[i][j] = max(c[i - 1][j], c[i][j - 1]); } } } return c[len1][len2]; }
原文链接:https://yq.aliyun.com/articles/705124
关注公众号

低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。

持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。

转载内容版权归作者及来源网站所有,本站原创内容转载请注明来源。

文章评论

共有0条评论来说两句吧...

文章二维码

扫描即可查看该文章

点击排行

推荐阅读

最新文章