原文:算法起步之动态规划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. 基于visual Studio2013解决面试题之1305字符串所有子集

     题目

  2. bottle-session 0.2 : Python Package Index

    bottle-session 0.2 : Python Package Index bottle-session 0.2 Download bottle-session-0.2.tar.gz Redi ...

  3. 我的mysql数据库sql优化原则

    原文 我的mysql数据库sql优化原则 一.前提 这里的原则 只是针对mysql数据库,其他的数据库 某些是殊途同归,某些还是存在差异.我总结的也是mysql普遍的规则,对于某些特殊情况得特殊对待. ...

  4. Spring Boot 分布式Session状态保存Redis

    在使用spring boot做负载均衡的时候,多个app之间的session要保持一致,这样负载到不同的app时候,在一个app登录之后,而打到另外一台服务器的时候,session丢失. 常规的解决方 ...

  5. Eclipse完美汉化教程

    首先我们打开http://www.eclipse.org/babel/downloads.php下载语言包. 方法一:可以复制图片里的地址通过Eclipse下载,Help→Install New So ...

  6. 页面爬虫(获取其他页面HTML)加载到自己页面

    //前台 <div id="showIframe"></div> $(document).ready(function() { var url = &quo ...

  7. android 实现跳动频谱 DEMO

    package com.terry.AudioFx; import android.app.Activity; import android.content.Context; import andro ...

  8. 10个优秀的 HTML5 &amp; CSS3 下拉菜单制作教程

    下拉菜单是一个非经常见的效果.在站点设计中被广泛使用.通过使用下拉菜单.设计者不仅能够在站点设计中营造出色的视觉吸引力,但也能够为站点提供了一个有效的导航方案.使用 HTML5 和 CSS3 能够更e ...

  9. awk 正则表达式

    awk 正则表达式.正则运算符详细介绍 前言:使用awk作为文本处理工具,正则表达式是少不了的. 要掌握这个工具的正则表达式使用.其实,我们不必单独去学习它的正则表达式.正则表达式就像一门程序语言,有 ...

  10. MySQL备份方案-->(利用mysqldump以及binlog二进制日志)

                                                         MySQL备份方案-->(利用mysqldump以及binlog二进制日志) 随着数据不 ...