原文:算法起步之动态规划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. PHP - 字符串操作

    第8章 字符串处理 学习要点: 1.字符串格式化 2.操作子字符串 3.字符串比较 4.查找替换字符串 5.处理中文字符 在每天的编程工作中,处理.调整以至最后控制字符串是很重要的一部分,一般也认为这 ...

  2. 使用代码辅助生成工具CodeSmith -- 生成NHibernate的映射文件

    首先下载CodeSmith工具:在百度云中,在CodeSmith文件夹中. 安装,使用激活工具激活. 然后下载NHibernate模板,也是在百度云中,在CodeSmith文件夹中. 之后直接点击NH ...

  3. 11181 - Probability|Given

    N friends go to the local super market together. The probability of their buying something from them ...

  4. nexus搭建

    Nexus是Maven仓库管理软件,可以用来搭建私服.主页 http://www.sonatype.org/nexus/ 下载地址 http://www.sonatype.org/nexus/down ...

  5. rowid结构浅析

    select rowid from dual AAAAB0AABAAAAOhAAA rowid结构如下: 对象号    文件号   块号   行号 XXXXXX    XXX     XXXXXX X ...

  6. 基于visual Studio2013解决面试题之0905子串数量

     题目

  7. yw info

    浙江省公开招聘聘任制公务员公告 浙江省公开招聘聘任制公务员公告-浙江组织工作网-浙江在线 浙江省公开招聘聘任制公务员公告

  8. 关于mysql5.6.13的一个疑问

    现在在做一个系统 使用了这么一个查询 select a.id,a.fdate,a.fbillno,e.fname as fwarehousename,a.fnote,c.fname as fsuppl ...

  9. 网页内容的html标签补全和过滤的两种方法

    网页内容的html标签补全和过滤的两种方法: 假设你的网页内容的html标签显示不全,有些表格标签不完整而导致页面混乱,或者把你的内容之外的局部html页面给包括进去了,我们能够写个函数方法来补全ht ...

  10. 国际化之ResourceBundle

    软件在开发时要能使它同时应对世界不同地区和国家的使用,针对不同地区和国家的访问,提供相应的,符合使用者阅读习惯的操作环境,这就必须要有国际化的概念,国际化又称为“i18n”:international ...