zoukankan      html  css  js  c++  java
  • 第11章:最长公共子序列(LCS:Longest Common Subsequence)

    方法:动态规划 《算法导论》P208

    最优子结构 + 重叠子问题

     

    设xi,yi,为前i个数(前缀)

    设c[i,j]为xi,yi的LCS的长度

     

    c[i,j] = 0 (i ==0 || j == 0)

    c[i,j] = a[i-1,j-1] + 1 (i,j>0 &&xi=yi)

    c[i,j] = max(c[i,j-1],c[i-1,j])

     

     

     

     

     

    求LCS(Xm-1 , Y)的长度与LCS(X , Yn-1)的长度,这两 个问题不是相互独立的:两者都需要求LCS(Xm-1,Yn-1)的长度。

     

    【最长公共子序列的结构】

    设序列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 的最长公共子序列。

     

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

     

     

     

    由于在所考虑的子问题空间中,总共只有θ(m*n)个不同的 子问题,因此,用动态规划算法自底向上地计算最优值能提高算法的效率。

     

    【编码实现】

    输出两个数组c[0..m ,0..n]和b[1..m ,1..n]。其中c[i,j]存储

    Xi 与Yj 的最长公共子序列的长度,b[i,j]记录指示c[i,j]的值是由哪一个子问题的解达到的,

    这在构造最长公共子序列时要用到。最后,X 和Y 的最长公共子序列的长度记录于c[m,n]

    中。

     

    【相似的解决方法:构造矩阵】

     

     

    import java.util.Random;

     

    public class LCS{

     public static void main(String[] args){

      int substringLength1 = 20;

      int substringLength2 = 20;

     

      String x = GetRandomStrings(substringLength1);

      String y = GetRandomStrings(substringLength2);

     

      Long startTime = System.nanoTime();

     

      int[][] opt = new int[substringLength1 + 1][substringLength2 + 1];

     

      for(int i = substringLength1 - 1;i>=0;i--){

       for(int j =substring2 -1;j>=0;j--){

        if(x.charAt(i) =  y.charAt(j))

         opt[i][j] = opt[i+1][j+1] + 1;

        else

         opt[i][j] = Math.max(opt[i+1][j],opt[i][j+1]);

       }

      }

     

      System.out.println("substring1:"+x);

      System.out.println("substring2:"+y);

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

      int i = 0, j = 0;

      while (i < substringLength1 && j < substringLength2){

       if (x.charAt(i) == y.charAt(j)){

        System.out.print(x.charAt(i));

        i++;

        j++;

       } else if (opt[i + 1][j] >= opt[i][j + 1])

         i++;

       else

       j++;

      }

      Long endTime = System.nanoTime();

     

     }

    }

  • 相关阅读:
    Visual C++ 2005如何引用静态链接库(.lib)
    CodeSnippets: Recursively remove all .svn directories [shell] [svn] [bash]
    静态连接库的生成和使用
    vc生成静态库例子
    Remove the .pyc files from current directory tree and from svn (Python recipe) by Senthil Kumaran
    boost 1.52在windows下的配置
    CMake Cross Platform Make
    std::equal_range
    Windows环境下使用Boost
    Js$.extend方法使方法参数更灵活
  • 原文地址:https://www.cnblogs.com/lsx1993/p/4841553.html
Copyright © 2011-2022 走看看