最长公共子序列
来源:互联网 发布:盖革计数器 知乎 编辑:程序博客网 时间:2024/04/30 18:34
问题描述:一个序列 S ,如果分别是两个或多个已知序列的子序列,且是所有符合此条件序列中最长的,则 S 称为已知序列的最长公共子序列。而最长公共子串(要求连续)和最长公共子序列是不同的。
LCS的最优子结构
设 X={x1, x2, x3, x4,..., xm} 和 Y={y1, y2, y3, y4,..., yn} 为两个序列,并设 Z={z1, z2, z3, z4,..., zk} 为 X 与 Y 的任意一个LCS,则:
- 若xm=yn,则zk=xm=yn 且Zk-1是Xm-1和Yn-1的一个LCS
- 若xm≠yn且zk≠xm ,则Z是Xm-1和Y的一个LCS
- 若xm≠yn且zk≠yn ,则Z是X和Yn-1的一个LCS
重叠子问题
由LCS问题的最优子结构可得递归式
满足了动态规划的两个条件之后,该问题可以采用备忘录(也叫打表)思想进行求解,下面举例说明实际操作过程:
设有两个序列x="ABCBDAB"(m=7)和y="BDCABA"(n=6)
步骤一:打表,按行填充二维数组,填充规则参照根据最优子结构得出的递归式(其中第0行第0列作为哨兵可全部填0),填充结果如下
步骤二:从数组的最右下角开始,每遇到朝左上的箭头,则输出字符,最后可得LCS={BCBA}
代码实现如下:
public class Solution {enum Direction {L, U, UL, DEFAULT};Item NULL = new Item(0, Direction.DEFAULT);public String LCS(String x, String y) {//需要第0列作哨兵,所以需要长度+1int lenx = x.length() + 1, leny = y.length() + 1;Item c[][] = new Item[lenx][leny];for (int i = 0; i < lenx; i++) {c[i][0] = NULL;}for (int j = 0; j < leny; j++) {c[0][j] = NULL;}for (int i = 1; i < lenx; i++) {for (int j = 1; j < leny; j++) {if (x.charAt(i - 1) == y.charAt(j - 1)) {c[i][j] = new Item(c[i - 1][j - 1].val + 1, Direction.UL);} else {if (c[i][j - 1].val > c[i - 1][j].val) {c[i][j] = new Item(c[i][j - 1].val, Direction.L);} else {c[i][j] = new Item(c[i - 1][j].val, Direction.U);}}}}StringBuilder result = new StringBuilder(c[lenx - 1][leny - 1].val);for (int i = lenx - 1; i >= 0;) {for (int j = leny - 1; j >= 0;) {switch (c[i][j].direct) {case L:j -= 1;break;case U:i -= 1;break;case UL:result.insert(0, x.charAt(i - 1));i -= 1;j -= 1;break;case DEFAULT:default:return result.toString();}}}return result.toString();}class Item {int val;Direction direct;Item(int v, Direction d) {this.val = v;this.direct = d;}}}
另外,需要说明一点,两个字符串的LCS可能存在多个,那么允许lcs(x,y)和lcs(y,x)返回的结果不一样,只需要保证长度相等即可
0 0
- 最长公共子序列
- 最长公共子序列
- 最长公共子序列
- 最长公共子序列
- 最长公共子序列...
- 最长公共子序列
- 最长公共子序列
- 最长公共子序列
- 最长公共子序列
- 最长公共子序列
- 最长公共子序列
- 最长公共子序列
- 最长公共子序列
- 最长公共子序列
- 最长公共子序列
- 最长公共子序列
- 最长公共子序列
- 最长公共子序列
- 在Mac上配置cocos2d-x 3.0,xcode5资源无法刷新的问题
- EJB之Message-Driven Bean
- Servlet总结
- SSI 架构
- EJB之拦截器
- 最长公共子序列
- ubuntu 安装 pydev 后,在windows->preference中没有出现pydev的解决办法
- EJB之Web Service
- 快速部署SSI框架
- cocos2dx 动画第一个demo
- 多变量线性回归的解析解
- 遇到了一个HttpURLConnection乱码问题:结果是JVM file.encoding错误
- hdu 2546:饭卡
- hdu 2159:FATE