最长公共子序列(LCS)

定义:在序列X和序列Y中同时出现的元素,按照脚标从小到大排列的这样的序列。

        String x = "ABCBDABGGGTT";
        String y = "BDCABATGGGTT";

x,y的最长公共子序列为BCBAGGGTT;

package shu_quan.dynamic;import java.util.ArrayList;
/*** * @author quan*777代表两个x,y序列长度相同且最长公共子序列是Xn和Yn的情况,存在相同的元素*444代表x,y两个序列长度不同且最长公共子序列是x和Yn-1的情况,*666代表x,y两个序列长度不同且最长公共子序列是Xn-1和Yn的情况,*/public class LongestCommonSubsequence {public static void main(String[] args) {//初始化两个字符序列String x1 = "ABCBDABGGGTT";String x2 = "BDCABATGGGTT";char[] x = x1.toCharArray();char[] y = x2.toCharArray();ArrayList<int[][]> ls = new ArrayList<>();ArrayList<int[][]> ls1 = longestCommonSubsequence(x,y,ls);int[][] b = ls.get(0);int[][] c = ls.get(1);//打印c矩阵for (int i = 0; i < c.length; i++) {for (int j = 0; j < c[0].length; j++) {System.out.print(c[i][j]+"        ");}System.out.println();}System.out.println("===================================================================");//打印b矩阵for (int i = 0; i < b.length; i++) {for (int j = 0; j < b[0].length; j++) {System.out.print(b[i][j]+"        ");}System.out.println();}//构造LCSStringBuilder sb = new StringBuilder();printLongestCommonSubsequence(sb,b,x,x.length,y.length);System.out.println(sb.toString());}/**重构最优解LCS*/private static void printLongestCommonSubsequence(StringBuilder sb, int[][] b, char[] x, int i, int j) { if(i==0 || j==0)return;//777代表两个x,y序列长度相同且最长公共子序列是Xn和Yn的情况,存在相同的元素if(b[i][j] == 777) {printLongestCommonSubsequence(sb,b,x,i-1,j-1);sb.append(x[i-1]);//444代表x,y两个序列长度不同且最长公共子序列是x和Yn-1的情况}else if(b[i][j] == 444) {printLongestCommonSubsequence(sb,b,x,i,j-1);//666代表x,y两个序列长度不同且最长公共子序列是Xn-1和Yn的情况}else{printLongestCommonSubsequence(sb,b,x,i-1,j);}}/**把c矩阵和b矩阵放入容器中返回容器。*/private static ArrayList<int[][]> longestCommonSubsequence(char[] x, char[] y, ArrayList<int[][]> ls) {int m = x.length;int n = y.length;int[][] c = new int[m+1][n+1];int[][] b = new int[m+1][n+1];//c[i][j]表示xi和yi的LCS的长度,当i或者j等于0,序列的长度也为0.for (int i = 0; i < c.length; i++) {c[i][0] = 0;}for (int i = 0; i < c[0].length; i++) {c[0][i] = 0;}for(int i=1; i <= m; i++) {for(int j=1; j <=n; j++) {if(x[i-1] == y[j-1]) {c[i][j] = c[i-1][j-1] + 1;b[i][j] = 777;}else if(c[i-1][j]>=c[i][j-1]){c[i][j] = c[i-1][j];b[i][j] = 666;}else {c[i][j] = c[i][j-1];b[i][j] = 444;                    }}}ls.add(b);ls.add(c);return ls;}}

运行结果:

0        0        0        0        0        0        0        0        0        0        0        0        0        
0        0        0        0        1        1        1        1        1        1        1        1        1        
0        1        1        1        1        2        2        2        2        2        2        2        2        
0        1        1        2        2        2        2        2        2        2        2        2        2        
0        1        1        2        2        3        3        3        3        3        3        3        3        
0        1        2        2        2        3        3        3        3        3        3        3        3        
0        1        2        2        3        3        4        4        4        4        4        4        4        
0        1        2        2        3        4        4        4        4        4        4        4        4        
0        1        2        2        3        4        4        4        5        5        5        5        5        
0        1        2        2        3        4        4        4        5        6        6        6        6        
0        1        2        2        3        4        4        4        5        6        7        7        7        
0        1        2        2        3        4        4        5        5        6        7        8        8        
0        1        2        2        3        4        4        5        5        6        7        8        9        
===================================================================
0        0            0            0            0            0            0            0            0            0            0            0            0        
0        666        666        666        777        444        777        444        444        444        444        444        444        
0        777        444        444        666        777        444        444        444        444        444        444        444        
0        666        666        777        444        666        666        666        666        666        666        666        666        
0        777        666        666        666        777        444        444        444        444        444        444        444        
0        666        777        666        666        666        666        666        666        666        666        666        666        
0        666        666        666        777        666        777        444        444        444        444        444        444        
0        777        666        666        666        777        666        666        666        666        666        666        666        
0        666        666        666        666        666        666        666        777        777        777        444        444        
0        666        666        666        666        666        666        666        777        777        777        444        444        
0        666        666        666        666        666        666        666        777        777        777        444        444        
0        666        666        666        666        666        666        777        666        666        666        777        777        
0        666        666        666        666        666        666        777        666        666        666        777        777        
BCBAGGGTT

C[i][j]的值为序列Xi和Yj的最长公共子序列的值。

矩阵b比较抽象:构造LCS。

以下图(来自算法导论)说明数字777,444,666的含义,代表了计算c的选择指向↖、←、↑ ,b[i][j]的指向对应计算c[i][j]时所选的子问题最优解,按照箭头的方向就能够追踪得到任意c[i][j]最长公共子序列。使用递归的方式求LCS。

Java动态规划求最长公共子序列(LCS)相关推荐

  1. 动态规划解最长公共子序列(LCS)(附详细填表过程)

    目录 相关概念 子序列形式化定义: 公共子序列定义: 最长公共子序列(以下简称LCS): 方法 蛮力法求解最长公共子序列: 动态规划求解最长公共子序列: 分析规律: 做法: 伪代码: 下面演示下c数组 ...

  2. 动态规划之最长公共子序列(LCS)

    最长公共子序列(LCS,Longest Common Subsequence).其定义是,一个序列 S ,如果分别是两个或多个已知序列的子序列,且是所有符合此条件序列中最长的,则 S 称为已知序列的最 ...

  3. 动态规划_求最长公共子序列LCS

    学习动态规划有段时间了,我自己的感觉是看到题解很明白,但是拿到新题就后脑冒汗了,费解!我知道这其实是理解不深的缘故,动态规划是解决一类问题的方法,而不是解决某个问题的解法.今天我试着去感觉一下怎么去思 ...

  4. 【谈谈】动态规划——求最长公共子序列

    首先,我们要搞清楚所谓最长公共子序列的概念.不然很容易把它和最长公共子串混淆,两者区别是:子序列只需要字符保持相对顺序,并不要求像公共字串那样组成字符还需连续. 问题: 给定两个字符串数组序列: X[ ...

  5. [dp]leetcode1143:最长公共子序列LCS (medium)

    题目: 题解: 动态规划的经典例题,可参考晴神的算法笔记 首先先使用暴力法思考吧,设t1和t2的长度分别为m和n,那么对两个字符串中的每个字符,分别只有选和不选两个决策,而得到两个子序列后,比较两个子 ...

  6. 动态规划算法解最长公共子序列LCS问题

    动态规划算法解LCS问题 作者 July 二零一零年十二月三十一日 本文参考:微软面试100题系列V0.1版第19.56题.算法导论.维基百科. 第一部分.什么是动态规划算法 ok,咱们先来了解下什么 ...

  7. Algorithm:C++/python语言实现之求旋转数组最小值、求零子数组、求最长公共子序列和最长公共子串、求LCS与字符串编辑距离

    Algorithm:C++/python语言实现之求旋转数组最小值.求零子数组.求最长公共子序列和最长公共子串.求LCS与字符串编辑距离 目录 一.求旋转数组最小值 1.分析问题 2.解决思路 二.求 ...

  8. 最长公共子序列php,动态规划(最长公共子序列LCS)

    概念 求解决策过程最优化的结果 (可能有多个) 把多阶段过程转化为一系列单阶段过程,利用各阶段之间的关系,逐个求解 计算过程中会把结果都记录下,最终结果在记录中找到. 举例 求两个字符串的最长公共子序 ...

  9. 算法导论-----最长公共子序列LCS(动态规划)

    目录 一.概念梳理 二.最长公共子序列解决方案 方案1:蛮力搜索策略 方案2:动态规划策略 三.C代码实现 实现1 实现2(空间优化) 一.概念梳理   1. 子序列(subsequence): 一个 ...

最新文章

  1. 2019全球AI争夺战最新汇总
  2. Django startproject的问题
  3. C++ semi implicit euler半隐式向后欧拉法解算常微分方程(附完整源码)
  4. C语言程序设计 | 大端小端存储解析以及判断方法
  5. linux下cron定时任务的总结
  6. cogs2840. 二叉查找树
  7. 【小梅哥SOPC学习笔记】系统时钟的使用
  8. 财务与IIT的发展正在质变
  9. ftp://hxtech.com
  10. 关于window.showModalDialog遭遇frameset不能初始化对话框大小
  11. 程序员喜欢的5款最佳代码比较工具
  12. 上银驱动器使用手册_禾川伺服驱动器说明书
  13. 加快建设泛在电力物联网:万物互联 驶向数字经济蓝海
  14. HSB”、lab、CMYK、RGB有什么区别
  15. python写整数逆位运算_整数逆位运算
  16. 迪杰特斯拉算法Python版本
  17. 【计算机网络】物理层 : 香农定理 ( 噪声 | 信噪比 | 香农定理 | “香农定理“公式 | “香农定理“ 计算示例 | “奈氏准则“ 与 “香农定理“ 对比 与 计算示例)★
  18. 机器学习cae_关于CAE 仿真对HPC需求的迷思-Part 1
  19. rdesktop参数
  20. 如何用AR Engine开发一个虚拟形象表情包?

热门文章

  1. vs2010一运行就报错deven.exe assert failure 解决方法,卸载系统中.netFramework最新版本的(简体中文)...
  2. Shell脚本学习-阶段十三-在 Linux 中使用日志来排错
  3. 首份“中国大数据的社会经济价值研究报告”发布
  4. win2008支持mysql asp.net_Win7、win2008中让IIS7支持asp的方法
  5. Eclipse环境安装Python插件PyDev
  6. asp.net c# 常见面试试题总结汇总(含答案)
  7. 马哥语录第一季第二集
  8. 戏说前端 JavaScript 之『防抖节流』基础知识
  9. HDU-4145 A Simple Problem 简单数论
  10. 提示,请选择有效的文件