问题描述:

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

注意:

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

思路分析:

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

最长公共子序列的结构

设序列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. C++重载输入流复习

    C++重载输入流 #include <bits/stdc++.h> using namespace std; struct Point { int x, y; Point(int xx, ...

  2. Spring统一返回Json工具类,带分页信息

    前言: 项目做前后端分离时,我们会经常提供Json数据给前端,如果有一个统一的Json格式返回工具类,那么将大大提高开发效率和减低沟通成本. 此Json响应工具类,支持带分页信息,支持泛型,支持Htt ...

  3. ACM 继续畅通工程

    Problem Description 省政府"畅通工程"的目标是使全省任何两个村庄间都可以实现公路交通(但不一定有直接的公路相连,只要能间接通过公路可达即可).现得到城镇道路统计 ...

  4. WebRTC 音频算法 附完整C代码

    WebRTC提供一套音频处理引擎, 包含以下算法: AGC自动增益控制(Automatic Gain Control) ANS噪音抑制(Automatic Noise Suppression) AEC ...

  5. 豌豆夹Redis解决方案Codis源码剖析:Proxy代理

    豌豆夹Redis解决方案Codis源码剖析:Proxy代理 1.预备知识 1.1 Codis Codis就不详细说了,摘抄一下GitHub上的一些项目描述: Codis is a proxy base ...

  6. 20160214.CCPP体系详解(0024天)

    程序片段(01):CGI.c 内容概要:CGI-cloud #define _CRT_SECURE_NO_WARNINGS #include <stdio.h> int main01(vo ...

  7. Objective-C语法概述

    Objective-C语法概述 简称OC 面向对象的C语言 完全兼容C语言 可以在OC里面混入C/C++代码 可以开发IOS和Mac OS X平台应用 语法预览 关键字 基本上都是以@开头(为了与C语 ...

  8. 向VS中添加个PATH怎么样?

    属性中,有个调试的目录,向"环境"中添加: PATH="your path";$(PATH) 可以调试用一下.

  9. python 如何优雅地退出子进程

    python 如何优雅地退出子进程 主进程产生子进程,子进程进入永久循环模式.当主进程要求子进程退出时,如何能安全地退出子进程呢? 参考一些代码,我写了这个例子.运行之后,用kill pid试试.pi ...

  10. Gazebo機器人仿真學習探索筆記(二)基本使用說明

    在完成Gazebo7安裝後,需要熟悉Gazebo,方便之後使用. 部分源代碼可以參考:https://bitbucket.org/osrf/gazebo/src/ 如果還沒有安裝請參考之前內容完成安裝 ...