LCS引论

在这篇博文中,博主要给大家讲一个算法----最长公共子序列(LCS)算法。我最初接触这个算法是在高中学信息学竞赛的时候。那时候花了好长时间理解这个算法。老师经常说,这种算法是母算法,即从这种算法中能衍生出许许多多的子算法。是的,博主在大二的算法导论考试中,就被LCS衍生的子算法“坑”了。当时一道动态规划题目,大概是要写一列书中放置书架的问题。博主联想到了LCS,但是最后还是只是用暴力求解法解出了那道题目,甚是遗憾。在这里,我也对此算法做一个详解。

优化子结构

首先,我们来看优化子结构:

设X=(x 1 , ..., x m ) 、Y=(y 1 , ..., y n )  是两个序列,Z=(z 1 , ..., z k ) 是X 与Y 的LCS ,我们有:

⑴     如果xm =yn,  则zk =xm = yn , Zk-1 是Xm-1 和Yn-1 的LCS , 即 :

LCS XY  = LCS X m-1 Y n-1 + <xm =yn >.

⑵     如果xm ≠ yn , 且zk≠ xm , 则Z 是X m-1 和Y 的

LCS , 即  LCS XY = LCS X m-1 Y

⑶     如果xm ≠ yn ,且zk≠ yn ,则Z 是X 与Y n-1 的LCS ,即 :

LCS XY = LCS XY n-1

构造C[m,n]数组表示xm 、yn 的LCS长度,因此,求得X和Y的优化解结构的递归方程为:

C[i, j] = 0 if i=0  或 j=0

C[i, j] = C[i-1, j-1] + 1 if i, j>0  且 x i  = y j

C[i, j] = Max(C[i, j-1], C[i-1, j]) if i, j>0  且 x i ≠ y j

在存储LCS的时候,我们根据已经构造好的B[m,n]来寻找全部的LCS。

如果B[m,n]=0,说明X和Y当前比对的字符相同,因此我们把X和Y都向前一个字符,再进行比对。

如果B[m,n]=1,说明xm ≠ yn , 且zk≠ xm ,此时我们只用把X向前移一位,再进行比对。

如果B[m,n]=3,说明xm ≠ yn ,且zk≠ yn,此时我们需要把Y向前移动一位,再进行比对。

如果B[m,n]=2,说明c[i - 1][j] = c[i][j - 1],我们需要将两个字符串依次向前移动一位,进行比对

关键的数据结构及简单说明

C[m,n]: C[i,j] 是X i 与Y j 的LCS 的长度;

B[m,n]: B[i,j] 是指针 ,指向计算C[i,j] 时所选择的子问题的优化解所对应的C 表的表项。通俗的说,B[m,n]记录的是轨迹;

public static String[] Log:存储全部LCS字符串;

public static char[] lcs:字符数组,存储

TreeSet<String> tree = new TreeSet<String>():将LCS数组存入Tree集合中,供打印使用。

示例程序

 package test;

import java.util.Scanner;

import java.util.TreeSet;

public class LCS {

public static StringBuffer X;

public static StringBuffer Y;

public static int m;

public static int n;

public static int len;

public static int[][] b;

public static int[][] c;

public static String[] Log;

public static char[] lcs;

public final static int MAX = 100;

public static int boardlen;

public static void main(String[] args) {

Log = new String[MAX];

LCS lcs = new LCS();

Scanner in = new Scanner(System.in);

System.out.println("string X:");

X = new StringBuffer(in.next());

System.out.println("string Y:");

Y = new StringBuffer(in.next());

lcs_length();

System.out.println("LCS:");

store_lcs(m, n, len);

PrintLCS();

X.setLength(0);

Y.setLength(0);

in.close();

}

public static void lcs_length() {

m = X.length();

n = Y.length();

lcs = new char[m + 1];

boardlen = 0;

c = new int[m + 1][n + 1];

b = new int[m + 1][n + 1];

for (int i = 1; i <= m; i++)

c[i][0] = 0;

for (int j = 0; j <= n; j++)

c[0][j] = 0;

for (int i = 1; i <= m; i++){

for (int j = 1; j <= n; j++) {

if (X.charAt(i - 1) == Y.charAt(j - 1)) {

c[i][j] = c[i - 1][j - 1] + 1;

b[i][j] = 0;

} else if (c[i - 1][j] > c[i][j - 1]) {

c[i][j] = c[i - 1][j];

b[i][j] = 1;

} else if (c[i - 1][j] == c[i][j - 1]) {

c[i][j] = c[i - 1][j];

b[i][j] = 2;

} else {

c[i][j] = c[i][j - 1];

b[i][j] = 3;

}

}

}

len = c[m][n];

}

public static void store_lcs(int m, int n, int Len) {

if (m == 0 || n == 0) {

Log[boardlen] = new String(lcs);

boardlen++;

} else {

if (b[m][n] == 0) {

lcs[Len] = X.charAt(m - 1);

Len--;

store_lcs(m - 1, n - 1, Len);

} else if (b[m][n] == 3) {

store_lcs(m, n - 1, Len);

} else if (b[m][n] == 1) {

store_lcs(m - 1, n, Len);

} else {

store_lcs(m, n - 1, Len);

store_lcs(m - 1, n, Len);

}

}

}

public static void PrintLCS() {

TreeSet<String> tree = new TreeSet<String>();

for (int i = 0; i <boardlen; i++) {

tree.add(Log[i]);

}

String[] string = new String[tree.size()];

for (int i = 0; i < string.length; i++) {

string[i] = tree.pollFirst();

System.out.println(string[i]);

}

}

public void printit() {

for (int i = 0; i < Log.length; i++) {

if (Log[i] != null) {

System.out.println(Log[i]);

}

}

}

}

后序

程序经本人测试,能够运行出正确结果。以上仅供大家学习交流,转载请注明出处。

我的第一篇博客----LCS学习笔记的更多相关文章

  1. 第一篇博客:Hello World

    2016年10月10日,双十,好日子,决定开始写第一篇博客,标题想了会,就叫Hello World 吧,哈哈^_^. 首先感谢博客园的管理们能批准我的申请,记得在14年的时候申请过一次,竟然没申请通过 ...

  2. 我的第一篇博客 ——【ToDoList】小程序开发

    我是一只即将大四的大三狗,这是我的第一篇博客,说来惭愧.今年1月份,学校放寒假的时候开始自学的IOS,放假的时候比较起劲,看了一堆Object-C的视频,然后照着中英文对照的IOS基础开发教程,做了两 ...

  3. Hello World -- 第一篇博客

    今年注定是不寻常的一年,因为技术,接触了许多大牛.通过一篇篇博文,看到了大牛们勤奋好学.孜孜不倦的精神,于是决定也开个博客,向大牛学习. 博客开了,写点什么呢?奈何肚子里墨水不多,吐出来也多是白沫,不 ...

  4. “Hello, my first blog”------第一篇博客的仪式感

    本人在校大学生一枚,开通博客,主要是想记录自己的学习过程,分享自己的学习经历.记得大一的时候,很多不懂的操作和知识,都是在博客上找到了相应的解决办法.但比较讽刺的是,很多时候,曾经解决了的问题,当再次 ...

  5. C博客作业00—我的第一篇博客

    C博客作业00-我的第一篇博客 1. 你对网络专业或者计算机专业了解是怎样? 泛泛了解 - 原先只知道网络工程隶属于计算机工程学院,与院中其他专业一样,同样都需要学习大量的计算机基础知识,然后再分支学 ...

  6. Hello World -- 第一篇博客 -- 活着的意义

    今年注定是不寻常的一年,因为技术,接触了许多大牛.通过一篇篇博文,看到了大牛们勤奋好学.孜孜不倦的精神,于是决定也开个博客,向大牛学习. 博客开了,写点什么呢?奈何肚子里墨水不多,吐出来也多是白沫,不 ...

  7. Youcans 的第一篇博客

    这是我的第一篇博客. 今后我会将我的学习心得和总结在这里发布,与大家共享,共勉.

  8. 我的第一篇博客blog,笑哭

    我的第一篇博客blog Markdown学习 一级标题:#加一个空格 加 文字, 二级标题:加2个##以此类推 字体 粗体:hello world!字体前有二个星号,字体后有二个星号 斜体:hello ...

  9. 第一篇博客:HTML:background的使用

    开篇 我是一名程序员小白,这是我写的第一篇博客,在学习的路上难免会遇到难以解决的问题,我将会在这里写下我遇到的问题并附上解决方法 希望可以对各位有所帮助!! 我们在html中经常会遇到这样的问题 例如 ...

随机推荐

  1. Hadoop1 Centos伪分布式部署

    前言:       毕业两年了,之前的工作一直没有接触过大数据的东西,对hadoop等比较陌生,所以最近开始学习了.对于我这样第一次学的人,过程还是充满了很多疑惑和不解的,不过我采取的策略是还是先让环 ...

  2. 【Knockout.js 学习体验之旅】(3)模板绑定

    本文是[Knockout.js 学习体验之旅]系列文章的第3篇,所有demo均基于目前knockout.js的最新版本(3.4.0).小茄才识有限,文中若有不当之处,还望大家指出. 目录: [Knoc ...

  3. iOS 之UITextFiled/UITextView小结

    一:编辑被键盘遮挡的问题 参考自:http://blog.csdn.net/windkisshao/article/details/21398521 1.自定方法 ,用于移动视图 -(void)mov ...

  4. H5+JS+CSS3 综合应用

    慕课网新教程H5+JS+CSS3 实现的七夕言情主题效果已经出炉了 从设计到实现到录制与编写用了快1个月的时间,说真的这个案例是慕课定制的,我之前也没有系统的做过这样的一个效果,在实现的时候自己也重新 ...

  5. 在Windows上安装Elasticsearch 5.0

    在windows上安装Elasticsearch Elasticsearch可以使用.zip软件包安装在Windows上. elasticsearch-service.bat命令,它将设置Elasti ...

  6. [SQL] SQL 基础知识梳理(三) - 聚合和排序

    SQL 基础知识梳理(三) - 聚合和排序 [博主]反骨仔 [原文]http://www.cnblogs.com/liqingwen/p/5926689.html 序 这是<SQL 基础知识梳理 ...

  7. IDDD 实现领域驱动设计-上下文映射图及其相关概念

    上一篇:<IDDD 实现领域驱动设计-理解限界上下文> 距离上一篇有几天时间了,<实现领域驱动设计>第三章的内容都是围绕一个词-上下文映射图,我大概断断续续看了几天,总共看了两 ...

  8. DotNet生成随机数的一些方法

    在项目开发中,一般都会使用到“随机数”,但是在DotNet中的随机数并非真正的随机数,可在一些情况下生成重复的数字,现在总结一下在项目中生成随机数的方法. 1.随机布尔值: /// <summa ...

  9. SolrNet高级用法(分页、Facet查询、任意分组)

    前言 如果你在系统中用到了Solr的话,那么肯定会碰到从Solr中反推数据的需求,基于数据库数据生产索引后,那么Solr索引的数据相对准确,在电商需求中经常会碰到菜单.导航分类(比如电脑.PC的话会有 ...

  10. 利用js取到下拉框中选择的值

    现在的需求是:下拉框中要是选择加盟商让其继续选择学校,要是选择平台管理员则不需要选择学校.隐藏选择下拉列表. 选择枚举值: /// <summary> /// 平台角色 /// </ ...