原文:算法起步之动态规划LCS

前一篇文章我们了解了什么是动态规划问题,这里我们再来看动态规划另一个经典问题,最长公共子序列问题(LCS),什么是子序列,我们定义:一个给定序列将其中的0个或者多个元素去掉之后得到的序列就是他的子序列。例如序列x包含(a,b,c,b,d,a,b)那么序列y(b,c,d,b)就是x的一个子序列。公共子序列则是两个序列的公共的子序列,而最长公共子序列则是从两个序列的公共子序列中挑选出长度最长的子序列。

我们用我们说的动态规划的四步来分析这个问题。一刻画最长公共子序列的特征。假设序列X(包含X1,X2……Xm)而序列Y(Y1……Yn)而他们的最长公共子序列为Z(Z1……Zk);那么1如果Xm=Yn则Zk-1是Xm-1与Yn-1的最大公共子序列。2如果Xm!=Yn且Zk!=Xm那么Zk是Xm-1与Yn的最大公共子序列。3如果Xm!=Yn且Zk!=Yn那么Zk是Xm与Yn-1的最大公共子序列。通过这3种情况我们就可以将我们刚才的问题刻画成一个递归的问题。

我们可以通过递归的方式来求出最长公共子序列的长度。然后我们采用自底向上的方法来求出最优解。

public void lcsLength(String x,String y){
int xl=x.length();
int yl=y.length();
int[][] map=new int[xl+1][yl+1];
for (int i = 1; i <=xl; i++) {
for (int j = 1; j <=yl; j++) {
if (x.charAt(i-1)==y.charAt(j-1)) {
map[i][j]=map[i-1][j-1]+1;
}else {
if(map[i-1][j]>map[i][j-1]){
map[i][j]=map[i-1][j];
}else {
map[i][j]=map[i][j-1];
}
} }
}
System.out.println(map[xl][yl]);
} public static void main(String[] args) {
new LCS().lcsLength("abcab", "bcadd");
}

        
           这个图是一个例子运行时数组中值得变化,大家看了这个图应该比较清楚。

这样我们就求得了最长公共子序列的长度,然后我们可以根据改进算法把最长公共子序列打印出来。当然这里改进的方法有太多了,每个人可能都有自己的想法,我只提供一种方法供大家参考(并没有考虑运行效率等因素):

public class LCS {
private StringBuffer sb=new StringBuffer();
private int ox=0;
private int oy=0;
public void lcsLength(String x,String y){
int xl=x.length();
int yl=y.length();
int[][] map=new int[xl+1][yl+1];
for (int i = 1; i <=xl; i++) {
for (int j = 1; j <=yl; j++) {
if (x.charAt(i-1)==y.charAt(j-1)) {
map[i][j]=map[i-1][j-1]+1;
if (i>ox&&j>oy) {
if(map[i][j]>sb.length()){
sb.append(x.charAt(i-1));
ox=i;oy=j;
}
}else {
if (i>ox&&j<oy&&map[i][j]==sb.length()) {
sb.deleteCharAt(sb.length()-1);
sb.append(x.charAt(i-1));
ox=i;oy=j;
}
}
}else {
if(map[i-1][j]>map[i][j-1]){
map[i][j]=map[i-1][j];
}else {
map[i][j]=map[i][j-1];
}
}
}
}
System.out.println(map[xl][yl]);
System.out.println(sb.toString());
} public static void main(String[] args) {
new LCS().lcsLength("abcab", "bcadd"); }
}

友情提示:转载请注明出处【作者:idlear  博客:http://blog.csdn.net/idlear

算法起步之动态规划LCS的更多相关文章

  1. 算法起步之Bellman-Ford算法

    原文:算法起步之Bellman-Ford算法 从这篇开始我们开始介绍单源最短路径算法,他是图算法之一,我们前面说的贪心,图的遍历,动态规划都是他的基础,单源最短路径其实说的就是图中节点到节点的最短路径 ...

  2. 算法起步之A星算法

    原文:算法起步之A星算法 用途: 寻找最短路径,优于bfs跟dfs 描述: 基本描述是,在深度优先搜索的基础上,增加了一个启发式算法,在选择节点的过程中,不是盲目选择,而是有目的的选的,F=G+H,f ...

  3. 算法起步之Kruskal算法

    原文:算法起步之Kruskal算法 说完并查集我们接着再来看这个算法,趁热打铁嘛.什么是最小生成树呢,很形象的一个形容就是铺自来水管道,一个村庄有很多的农舍,其实这个村庄我们可以看成一个图,而农舍就是 ...

  4. 算法起步之Prim算法

    原文:算法起步之Prim算法 prim算法是另一种最小生成树算法.他的安全边选择策略跟kruskal略微不同,这点我们可以通过一张图先来了解一下. prim算法的安全边是从与当前生成树相连接的边中选择 ...

  5. 算法起步之Dijkstra算法

    原文:算法起步之Dijkstra算法 友情提示:转载请注明出处[作者 idlear    博客:http://blog.csdn.net/idlear/article/details/19687579 ...

  6. 算法 递归 迭代 动态规划 斐波那契数列 MD

    Markdown版本笔记 我的GitHub首页 我的博客 我的微信 我的邮箱 MyAndroidBlogs baiqiantao baiqiantao bqt20094 baiqiantao@sina ...

  7. 五大常见算法策略之——动态规划策略(Dynamic Programming)

    Dynamic Programming   Dynamic Programming是五大常用算法策略之一,简称DP,译作中文是"动态规划",可就是这个听起来高大上的翻译坑苦了无数人 ...

  8. 算法复习周------“动态规划之‘最长公共子序列’”&&《计蒜课》---最长公共子串题解

    问题描述: 这个问题其实很容易理解.就是给你两个序列X={x1,x2,x3......xm} Y={y1,y2,y3......ym},要求找出X和Y的一个最长的公共子序列. 例:Xi={A, B, ...

  9. 关于贪心算法的经典问题(算法效率 or 动态规划)

    如题,贪心算法隶属于提高算法效率的方法,也常与动态规划的思路相挂钩或一同出现.下面介绍几个经典贪心问题.(参考自刘汝佳著<算法竞赛入门经典>).P.S.下文皆是我一个字一个字敲出来的,绝对 ...

随机推荐

  1. boost之program_options库,解析命令行参数、读取配置文件

    一.命令行解析 tprogram_options解析命令行参数示例代码: #include <iostream> using namespace std; #include <boo ...

  2. Cocos2d-x3.0模版容器具体解释之二:cocos2d::Map&lt;K,V&gt;

    1.概述: 版本号: v3.0 beta 语言: C++ 定义在 "COCOS2DX_ROOT/cocos/base" 路径下的 "CCMap.h" 的头文件里 ...

  3. 高性能MySql进化论(四):Summary,Cache,Counter表的使用

    在实际的应用中,往往会定期的对一个周期内的系统数据进行统计分析.例如某购物网站定期的统计商品在一个月/年期内的销售情况,如果采用扫描所有相关表的方式在某个时间点进行统计分析, 由于数据量很大,以及表结 ...

  4. 如何制定AxureRP设计体系

    经常有朋友问我,如何在从来没有用过AxureRP的公司或者团队里面开始使用AxureRP做原型设计?这个问题对个体来说不存在,因为个人学习使用AxureRP时非常快速的,基本试着做几个原型实例就能把整 ...

  5. hdu 4812 D Tree(树的点分治)

    D Tree Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 102400/102400 K (Java/Others) Total ...

  6. 国际化之MessageFormat与占位符

    如果一个字符串文本中包含了多个与国际化相关的数据,可以使用MessageFormat类对这些数据进行批量处理. 例如: 在2016年1月9日的时候,一场台风导致了500间房屋的摧毁和¥1000000元 ...

  7. Servlet的学习之web路径问题

    在这个篇章中,我们来学习下在web开发过程中会碰到的路径写法问题. 在之前的web应用开发,尤其是Servlet的学习过程中,我们碰到多次要写路径的问题,这些路径并不统一,因此这里将大致说明下各个方法 ...

  8. WM_DRAWITEM与DrawItem()的讨论(自绘)

    http://blog.csdn.net/FlowShell/archive/2009/10/10/4648800.aspx 我在学习中经常遇到要重写DrawItem()的情况,但又有一个WM_DRA ...

  9. mssql数据库游标批量改动符合条件的记录

    //需求:因为项目刚上传,没有票数,为了表现出一定的人气,须要在一開始把各项目的票数赋一个值 , 但每一个项目不能一样,否则easy看出问题,呵呵 . DECLARE @Id varchar(50) ...

  10. 动态规划-hdoj-4832-百度之星2014初赛第二场

    Chess Problem Description 小度和小良近期又迷上了下棋.棋盘一共同拥有N行M列,我们能够把左上角的格子定为(1,1),右下角的格子定为(N,M).在他们的规则中,"王 ...