原文:算法起步之动态规划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. js打印

    js打印,其实是打印当前页面的内容,是调用 系统的js方法,来弹出 打印设置窗口,用法很简单. window.print()就行,有的考虑到 浏览器兼容性问题,会用到document.execComm ...

  2. CSDN高校俱乐部2013年秋季北京地区第一站“编程语言的应用及其发展”—北京联合大学

    2013年12月11日晚17:00.CSDN高校俱乐2013年秋季北京地区第一站“编程语言的应用及其发展”在北京联合大学进行. 首先,CSDN总部人员介绍CSDN俱乐部的改版以及线上编程挑战赛.CSD ...

  3. paip.提升用户体验---c++ qt自定义窗体(1)---标题栏的绘制

    源地址:http://blog.csdn.net/attilax/article/details/12343625 paip.提升用户体验---c++ qt自定义窗体(1)---标题栏的绘制 效果图: ...

  4. qt之正则表达式

    原地址:http://blog.csdn.net/phay/article/details/7304455 QRegExp是Qt的正则表达式类.Qt中有两个不同类的正则表达式.第一类为元字符.它表示一 ...

  5. boost::asio 连接管理11 如何关闭连接

    在实际产品运行中,对连接管理有了更新的认识,这里分享一下. shared_ptr管理连接对象的生命周期 shared_ptr的引用计数器决定了连接对象的生命周期.这里我说的连接对象就是在我的前文:ht ...

  6. java.io.EOFException解决

    主要错误提演示样例如以下: 严重: IOException while loading persisted sessions: java.io.EOFException 严重: Exception l ...

  7. Tomcat详细用法学习(五)

    本篇接上一篇<Tomcat详细用法学习(四)>,主要讲解Tomcat服务器的管理平台 我们可能会将很多web应用交给Tomcat,那么Tomcat服务器就要对我们这些载入的web应用进行管 ...

  8. asp.net检查服务器上目录或文件是否存在示例

    原文 asp.net检查服务器上目录或文件是否存在示例 asp.net为我们提供了文件系统对象了,对于目录与文件判断是否存在我们有System.IO.File.Exists与System.IO.Dir ...

  9. 党建凯,创新工场知乎团队Web前端工程师

    Nicholas C. Zakas谈怎样才能成为优秀的前端工程师: 昨天,我负责了Yahoo!公司组织的一次面试活动,感触颇深的是其中的应聘者提问环节.我得说自己对应聘者们提出的大多数问题都相当失望. ...

  10. android 5.0新特性

    Android Lollipop 面向开发人员的主要功能 Material Design 设计 注重性能 通知 以大屏幕呈现 以文档为中心 连接性能再上一级 高性能图形 音频处理功能更强 摄像头和视频 ...