问题描述:

问题】 求两字符序列的最长公共字符子序列

注意:

并不要求子串(字符串一)的字符必须连续出现在字符串二中。

思路分析:

最优子结构和重叠子问题的性质都具有,所以要采取动态规划的算法

最长公共子序列的结构

设序列X=x1, x2, …, xm和Y=y1, y2, …, yn的一个最长公共子序列Z=z1, z2, …, zk,则:

1.若xm=yn,则zk=xm=yn且Zk-1是Xm-1和Yn-1的最长公共子序列;

2.若xm≠yn且zk≠xm ,则Z是Xm-1和Y的最长公共子序列;

3.若xm≠yn且zk≠yn ,则Z是X和Yn-1的最长公共子序列。

其中Xm-1=x1, x2, …, xm-1,Yn-1=y1, y2, …, yn-1,Zk-1=z1, z2, …, zk-1。

子问题的递归结构

由最长公共子序列问题的最优子结构性质可知,要找出X=x1, x2, …, xm和Y=y1, y2, …, yn的最长公共子序列,可按以下方式递归地进行:当xm=yn时,找出Xm-1和Yn-1的最长公共子序列,然后在其尾部加上xm(=yn)即可得X和Y的一个最长公共子序列。当xm≠yn时,必须解两个子问题,即找出Xm-1和Y的一个最长公共子序列及X和Yn-1的一个最长公共子序列。这两个公共子序列中较长者即为X和Y的一个最长公共子序列。

由此递归结构容易看到最长公共子序列问题具有子问题重叠性质。

例如,在计算X和Y的最长公共子序列时,可能要计算出X和Yn-1及Xm-1和Y的最长公共子序列。而这两个子问题都包含一个公共子问题,即计算Xm-1和Yn-1的最长公共子序列。

与矩阵连乘积最优计算次序问题类似,我们来建立子问题的最优值的递归关系。用c[i,j]记录序列Xi和Yj的最长公共子序列的长度。其中Xi=x1, x2, …, xi,Yj=y1, y2, …, yj。

当i=0或j=0时,空序列是Xi和Yj的最长公共子序列,故c[i,j]=0。其他情况下,由定理可建立递归关系如下:

代码:

public class ComSubstr {  

    public static void main(String[] arg) {
        String a = "blog.csdn.net";
        String b = "csdn.blogt";
        comSubstring(a, b);
    }  

    private static void comSubstring(String str1, String str2) {
        char[] a = str1.toCharArray();
        char[] b = str2.toCharArray();
        int a_length = a.length;
        int b_length = b.length;
        int[][] lcs = new int[a_length + 1][b_length + 1];
        // 初始化数组
        for (int i = 0; i <= b_length; i++) {
            for (int j = 0; j <= a_length; j++) {
                lcs[j][i] = 0;
            }
        }
        for (int i = 1; i <= a_length; i++) {
            for (int j = 1; j <= b_length; j++) {
                if (a[i - 1] == b[j - 1]) {
                    lcs[i][j] = lcs[i - 1][j - 1] + 1;
                }
                if (a[i - 1] != b[j - 1]) {
                    lcs[i][j] = lcs[i][j - 1] > lcs[i - 1][j] ? lcs[i][j - 1]
                            : lcs[i - 1][j];
                }
            }
        }
        // 输出数组结果进行观察
        for (int i = 0; i <= a_length; i++) {
            for (int j = 0; j <= b_length; j++) {
                System.out.print(lcs[i][j]+",");
            }
            System.out.println("");
        }
        // 由数组构造最小公共字符串
        int max_length = lcs[a_length][b_length];
        char[] comStr = new char[max_length];
        int i =a_length, j =b_length;
        while(max_length>0){
            if(lcs[i][j]!=lcs[i-1][j-1]){
                if(lcs[i-1][j]==lcs[i][j-1]){//两字符相等,为公共字符
                    comStr[max_length-1]=a[i-1];
                    max_length--;
                    i--;j--;
                }else{//取两者中较长者作为A和B的最长公共子序列
                    if(lcs[i-1][j]>lcs[i][j-1]){
                        i--;
                    }else{
                        j--;
                    }
                }
            }else{
                i--;j--;
            }
        }
        System.out.print("最长公共字符串是:");
        System.out.print(comStr);
    }
}

输出结果:

0,0,0,0,0,0,1,2,2,2,2,
0,0,0,0,0,0,1,2,3,3,3,
0,0,0,0,0,0,1,2,3,4,4,
0,0,0,0,0,1,1,2,3,4,4,
0,1,1,1,1,1,1,2,3,4,4,
0,1,2,2,2,2,2,2,3,4,4,
0,1,2,3,3,3,3,3,3,4,4,
0,1,2,3,4,4,4,4,4,4,4,
0,1,2,3,4,5,5,5,5,5,5,
0,1,2,3,4,5,5,5,5,5,5,
0,1,2,3,4,5,5,5,5,5,5,
0,1,2,3,4,5,5,5,5,5,6,
最长公共字符串是:csdn.t  

## 我的微信二维码如下,欢迎交流讨论 ##

欢迎关注《IT面试题汇总》微信订阅号。每天推送经典面试题和面试心得技巧,都是干货!

微信订阅号二维码如下:

参考:

http://blog.csdn.net/v_JULY_v/article/details/6110269

http://www.programgo.com/article/74411986718/

LCS问题(最长公共子序列)-动态规划实现的更多相关文章

  1. C++求解汉字字符串的最长公共子序列 动态规划

        近期,我在网上看了一些动态规划求字符串最长公共子序列的代码.可是无一例外都是处理英文字符串,当处理汉字字符串时.常常会出现乱码或者不对的情况. 我对代码进行了改动.使用wchar_t类型存储字 ...

  2. nyoj 36-最长公共子序列 (动态规划,DP, LCS)

    36-最长公共子序列 内存限制:64MB 时间限制:3000ms Special Judge: No accepted:18 submit:38 题目描述: 咱们就不拐弯抹角了,如题,需要你做的就是写 ...

  3. 基于DP的LCS(最长公共子序列)问题

    最长公共子序列,即给出两个序列,给出最长的公共序列,例如: 序列1 understand 序列2 underground 最长公共序列undernd,长度为7 一般这类问题很适合使用动态规划,其动态规 ...

  4. LCS(最长公共子序列)动规算法正确性证明

    今天在看代码源文件求diff的原理的时候看到了LCS算法.这个算法应该不陌生,动规的经典算法.具体算法做啥了我就不说了,不知道的可以直接看<算法导论>动态规划那一章.既然看到了就想回忆下, ...

  5. 【ACM】最长公共子序列 - 动态规划

    最长公共子序列 时间限制:3000 ms  |  内存限制:65535 KB 难度:3   描述 咱们就不拐弯抹角了,如题,需要你做的就是写一个程序,得出最长公共子序列.tip:最长公共子序列也称作最 ...

  6. HDU 1159 Common Subsequence:LCS(最长公共子序列)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1159 题意: 求最长公共子序列. 题解: (LCS模板题) 表示状态: dp[i][j] = max ...

  7. POJ 1458 Common Subsequence (DP+LCS,最长公共子序列)

    题意:给定两个字符串,让你找出它们之间最长公共子序列(LCS)的长度. 析:很明显是个DP,就是LCS,一点都没变.设两个序列分别为,A1,A2,...和B1,B2..,d(i, j)表示两个字符串L ...

  8. NYOJ 36 LCS(最长公共子序列)

    题目链接: http://acm.nyist.edu.cn/JudgeOnline/problem.php?pid=36 最长公共子序列 时间限制:3000 ms  |  内存限制:65535 KB ...

  9. LCS(最长公共子序列)问题

    例题见挑战程序设计竞赛P56 解释:子序列是从原序列中按顺序(可以跳着)抽取出来的,序列是不连续的,这是其和子串最大的区别: 我们可以定义dp数组为dp[i][j],表示的是s1-si和t1-ti对应 ...

  10. LCS(最长公共子序列)

    这个问题很有意思,在生物应用中,经常需要比较两个(或多个)不同生物体的DNA片段.例如,某种生物的DNA可能为S1 = ACCGGTCGAGTGCGCGGAAGCCGGCCGAA,S2 = GTCGT ...

随机推荐

  1. Django Views(视图函数)

    http请求中产生两个核心对象: http请求:HttpRequest对象 http响应:HttpResponse对象 所在位置:django.http 之前我们用到的参数request就是HttpR ...

  2. 实验与作业(Python)-04 数据类型、数学函数与字符串

    截止日期 实验目标 继续熟悉for循环与turtle 数值运算符 math库常用函数 字符串转化为数值类型(int, float, complex) 字符串常用函数 实验内容 任务1.使用for代替w ...

  3. Linux Shell编程参考大全

    本文记录Linux Shell编程中常用基本知识,方便快速入门以及查询使用. 本文主要分为以下几个部分: 一.Shell中的变量 任何编程语言中,有关变量的定义,作用范围,赋值等都是最最基础的知识. ...

  4. 多线程(四) 实现线程范围内模块之间共享数据及线程间数据独立(Map集合)

    多个线程访问共享对象和数据的方式 1.如果每个线程执行的代码相同,可以使用同一个Runnable对象,这个Runnable对象中有那个共享数据,例如,买票系统就可以这么做. 2.如果每个线程执行的代码 ...

  5. Gi之(二)基础命令

    三个工作区域 使用Git之前,首先要弄清Git的三个管理区域,有助于理解Git的运行原理,以及每个Git命令对文件造成的影响. 对于任何一个文件,在本地的Git内部都有三种状态: l   已修改(mo ...

  6. springMVC源码分析--AbstractUrlHandlerMapping(三)

    上一篇博客springMVC源码分析--AbstractHandlerMapping(二)中我们介绍了AbstractHandlerMapping了,接下来我们介绍其子类AbstractUrlHand ...

  7. Picasso 完美兼容 OkHttp3.3,缓存优化两不误

    Tamic 专注移动开发!更多文章请关注http://www.jianshu.com/p/6241950f9daf csdn: http://blog.csdn.net/sk719887916/art ...

  8. VBA find方法

    Sub Sample() Dim sfzs As New Collection Dim ws, wbs, dbs As Worksheet Dim r As Long Set ws = ThisWor ...

  9. RxJava(七) 使用debounce操作符 优化app搜索功能

    欢迎转载,转载请标明出处: http://blog.csdn.net/johnny901114/article/details/51555203 本文出自:[余志强的博客] 一.抛出问题 现在几乎所有 ...

  10. Tomcat的系统安全管理

    Tomcat是一个Web容器,我们开发的Web项目运行在Tomcat平台,这就好比将一个应用嵌入到一个平台上面运行,要使嵌入的程序能正常运行,首先平台要能安全正常运行.并且要最大程度做到平台不受嵌入的 ...