【算法导论学习-29】动态规划经典问题02:最长公共子序列问题(Longest common subsequence,LCS)...
2019独角兽企业重金招聘Python工程师标准>>>
问题描述:序列X={x1,x2,…,xn},Y={y1,y2,…,yn},当Z={z1,z2…,zn}是X的严格递增下标顺序(可以不连续)的子集,也是Y的严格递增下标顺序(可以不连续)的子集,则Z是X和Y的公共子序列。例如X={A,B,C,B,D,A,B},Y={B,D,C,A,B,A},{B,C,A}、{B,C,B,A}、{B,D,A,B}都是X和Y的公共子序列。其中最长的公共子序列叫做Longest common subsequence,即经典的LCS。
具体点:char[]xArray和char[] yArray是字符数组,长度分别为m、n,求他们的LCS
【分析】自顶向下分析,二维数组cTable[i][j]记录xArray[0~i],yArray[0~j]的最长公共子序列的长度,则cTable[m][n]记录xArray[0~m],yArray[0~n]的最长公共子序列的长度。
1) 如果xArray[m]=yArray[n],表明最后一个元素xArray[m]是LCS中的元素,xArray[0~m],yArray[0~n]的最长公共子序列=xArray[0~m-1],yArray[0~n-1]的最长公共子序列+1,即cTable[m][n]=cTable[m-1][n-1]。
2) 如果xArray[m]!=yArray[n],表明xArray[m]、yArray[n]都有可能是LCS中的元素,但不能同时是。如果xArray[m]可能是,则xArray[0~m],yArray[0~n]的最长公共子序列=xArray[0~m],yArray[0~n-1]的最长公共子序列;如果yArray[n]可能是,则xArray[0~m],yArray[0~n]的最长公共子序列=xArray[0~m-1],yArray[0~n]的最长公共子序列。即cTable[m][n]=max(cTable[m-1][n], cTable[m][n-1])。
状态递归方程为:
参考《算法导论》P394页伪代码,java实现如下:
- /**
- * 创建时间:2014年9月3日 下午9:00:13
- * 项目名称:Test
- * @author Cao Yanfeng Peking University
- * @since JDK 1.6.0_21
- * 类说明: 最长公共子序列问题(Longest common subsequence,LCS)
- */
- public static void main(String[] args) {
- // TODO 自动生成的方法存根
- String x="ABCBDABCBACABC";
- String y="BDCABACABABCB";
- int temp=getLCSLength(x, y);
- System.out.println("\n长度为:"+temp);
- }
- public static int getLCSLength(String x,String y) {
- char[] xArray=x.toCharArray();
- char[] yArray=y.toCharArray();
- int m=xArray.length;
- int n=yArray.length;
- int [][] bTable=new int[m][n];
- /*cTable[i][j]记录xArray[0~i],yArray[0~j]的最长公共子序列的长度*/
- int [][] cTable=new int[m+1][n+1];
- for (int i = 0; i <m; i++) {
- for (int j = 0; j < n; j++) {
- if (xArray[i]==yArray[j]) {
- cTable[i+1][j+1]=cTable[i][j]+1;
- bTable[i][j]=2;//相等标记为2
- }else if (cTable[i][j+1]>=cTable[i+1][j]) {
- cTable[i+1][j+1]=cTable[i][j+1];
- bTable[i][j]=1;
- }else {
- cTable[i+1][j+1]=cTable[i+1][j];
- bTable[i][j]=3;
- }
- }
- }
- System.out.print("最大子数组为:");
- printLCS(xArray, bTable, m-1,n-1);
- return cTable[m][n];
- }
- /*输出最佳路径即最长公共子序列*/
- public static void printLCS (char[] xArray,int[][] bTable,int i,int j) {
- if (i==-1||j==-1) {
- return;
- }
- if (bTable[i][j]==2) {
- printLCS(xArray, bTable, i-1, j-1);
- System.out.print(xArray[i]);
- }else if (bTable[i][j]==1) {
- printLCS(xArray, bTable, i-1, j);
- }else {
- printLCS(xArray, bTable, i, j-1);
- }
- }
- }
/** * 创建时间:2014年9月3日 下午9:00:13 * 项目名称:Test * @author Cao Yanfeng Peking University* @since JDK 1.6.0_21 * 类说明: 最长公共子序列问题(Longest common subsequence,LCS)*/public static void main(String[] args) {// TODO 自动生成的方法存根String x="ABCBDABCBACABC";String y="BDCABACABABCB";int temp=getLCSLength(x, y);System.out.println("\n长度为:"+temp);}public static int getLCSLength(String x,String y) {char[] xArray=x.toCharArray();char[] yArray=y.toCharArray();int m=xArray.length;int n=yArray.length;int [][] bTable=new int[m][n];/*cTable[i][j]记录xArray[0~i],yArray[0~j]的最长公共子序列的长度*/int [][] cTable=new int[m+1][n+1];for (int i = 0; i <m; i++) {for (int j = 0; j < n; j++) {if (xArray[i]==yArray[j]) {cTable[i+1][j+1]=cTable[i][j]+1;bTable[i][j]=2;//相等标记为2}else if (cTable[i][j+1]>=cTable[i+1][j]) {cTable[i+1][j+1]=cTable[i][j+1];bTable[i][j]=1;}else {cTable[i+1][j+1]=cTable[i+1][j];bTable[i][j]=3;}}}System.out.print("最大子数组为:");printLCS(xArray, bTable, m-1,n-1);return cTable[m][n];}/*输出最佳路径即最长公共子序列*/public static void printLCS (char[] xArray,int[][] bTable,int i,int j) {if (i==-1||j==-1) {return;}if (bTable[i][j]==2) {printLCS(xArray, bTable, i-1, j-1);System.out.print(xArray[i]);}else if (bTable[i][j]==1) {printLCS(xArray, bTable, i-1, j);}else {printLCS(xArray, bTable, i, j-1);}}}
*****************************************
控制台输出:
最大子数组为:BCBACBACB
长度为:9
转载于:https://my.oschina.net/pangzhuzhu/blog/318106
【算法导论学习-29】动态规划经典问题02:最长公共子序列问题(Longest common subsequence,LCS)...相关推荐
- 动态规划—最长公共子序列问题 HDU-1159 Common Subsequence
动态规划-最长公共子序列问题 Common Subsequence [ HDU - 1159 ] A subsequence of a given sequence is the given sequ ...
- 触类旁通,经典面试题最长公共子序列应该这么答
作者 | labuladong 来源 | labuladong(ID:labuladong) [导读]最长公共子序列(Longest Common Subsequence,简称 LCS)是一道非常经 ...
- 动态规划表格法解决最长公共子序列(LCS)问题
3.5 最长公共子序列(LCS) 前言:图片是博主自己画的,转载请注明出处哦 3.5.1 问题描述 最长公共子序列(Longest Common Subseuence,LCS)问题:给定两个字符串,求 ...
- 两个字符串的最长公共子序列长度_程序员编程算法,解决文本相似度问题的最长公共子序列算法!...
在前面我讲解了如何通过最长公共子串来求解两个文本的相似度问题,但它有一定缺陷,举个例子,看下面的两个字符串 我爱吃小青菜和各种鲜水果. 我很爱吃青菜与各样水果. 上面两个字符串,如果通过计算子串来求相 ...
- 【动态规划】LeetCode 1143最长公共子序列
题目链接:力扣 思路: 动态规划: dp[i][j]表示text1[0:i) 和 text2[0:j)的最长公共子序列的长度 上述表示中,text1[0:i)的长度为i的前缀,text2[0:j)表示 ...
- 动态规划(四)--最长公共子序列
最长公共子序列问题 一种相似度的概念:一个给定的序列的子序列是将序列中零个或多个元素去掉之后得到的结果. 定义:给定一个序列X=<x1,x2,...,xm>,另一个序列Z=<z1,z ...
- 动态规划算法解最长公共子序列LCS问题
动态规划算法解LCS问题 作者 July 二零一零年十二月三十一日 本文参考:微软面试100题系列V0.1版第19.56题.算法导论.维基百科. 第一部分.什么是动态规划算法 ok,咱们先来了解下什么 ...
- 【动态规划】最长公共子序列与最长公共子串
1. 问题描述 子串应该比较好理解,至于什么是子序列,这里给出一个例子:有两个母串 cnblogs belong 比如序列bo, bg, lg在母串cnblogs与belong中都出现过并且出现顺序与 ...
- [Leetcode][第1143题][JAVA][最长公共子序列][LCS][动态规划]
[问题描述][中等] [解答思路] 时间复杂度:O(N^2) 空间复杂度:O(N^2) class Solution {public int longestCommonSubsequence(Stri ...
最新文章
- 很多程序员编程时都戴耳机?他们在听什么
- about diigo
- 企业研发管理工具应用分析
- Spring Boot由jar包转成war包
- app开发上传文件夹到服务器,uni-app 上传(图片上传实战)
- oauth基本流程和原理
- 前端学习(1870)vue之电商管理系统电商系统之配置message全局弹框组件
- C++学习之路 | PTA乙级—— 1014 福尔摩斯的约会 (20分)(精简)
- 对“善于提问,主动解决问题”的程序员的吐槽
- 在flex中显示gif
- 事件总线帧---Otto
- 复制oracle9i数据库,Oracle 10g 中Duplicate 复制数据库
- redis集群环境搭建入门
- COOKIE和SESSION之间的区别以及用法
- android gps 速度,Android 获取GPS速度
- 极光推送测试/新手适用/极光推送点击事件设置
- Qt5使用Poppler实现PDF阅读器
- 人工智能帮你生成中意的名字
- ubuntu 18.04 开启rc.local
- 用Java编写CGI小结
热门文章
- teamviewer解除5分钟商业限制最新方法,永久解决商业限制问题,无需一直改MAC地址
- Java 异常Exception e中e的getMessage()和toString()以及 e.printStackTrace();方法的区别
- Oracle shutdown immediate无法关闭数据库解决方法
- Android 解决通过自定义设置打开热点后手机搜索不到热点的问题。
- 线程池类似于多处理池?
- 在Android 6.0 Marshmallow(API 23)上弃用了getColor(int id)
- Win11未安装Defender怎么办?解决Win11未安装Defender的方法
- win11小组件怎么卸载 windows11卸载小组件的步骤方法
- win11的附件在哪 windows11附件的查看方法
- Java:PULLXML解析XML(内附jar包链接)