• 最长公共子序列--动态规划算法


    考虑最长公共子序列问题如何分解成子问题,设A=“a0,a1,…,am-1”,B=“b0,b1,…,bn-1”,并Z=“z0,z1,…,zk-1”为它们的最长公共子序列。不难证明有以下性质:

    (1) 如果am-1=bn-1,则zk-1=am-1=bn-1,且“z0,z1,…,zk-2”是“a0,a1,…,am-2”和“b0,b1,…,bn-2”的一个最长公共子序列;

    (2) 如果am-1!=bn-1,则若zk-1!=am-1,蕴涵“z0,z1,…,zk-1”是“a0,a1,…,am-2”和“b0,b1,…,bn-1”的一个最长公共子序列;

    (3) 如果am-1!=bn-1,则若zk-1!=bn-1,蕴涵“z0,z1,…,zk-1”是“a0,a1,…,am-1”和“b0,b1,…,bn-2”的一个最长公共子序列。

    问题的递归式写成:

    recursive formula

    回溯输出最长公共子序列过程:

    flow

    package test;
    
    import java.util.ArrayList;
    import java.util.List;
    
    /**
     * @ClassName: LCS
     * @Description: TODO
     * @author:
     * @Date: 2015-06-29 12:50:14
     */
    public class LCS {
    
        static int MAX=2;
        
        public static List<String> getLCS(int[][] c, int i, int j, String x, String y){
            List<String> t = new ArrayList<String>();
            if(i == 0 || j == 0){
                ;
            }else if(c[i][j] == 1){
                t = getLCS(c,i-1,j-1,x,y);
                if(t.size() == 0)
                    t.add("");
                for(int k = 0; k < t.size(); k++){
                    String v = t.get(k);
                    if(v.length() > 0){
                        int it = Integer.parseInt(v.substring(v.lastIndexOf("(")+1,v.lastIndexOf(",")));
                        if(i - it > 2){
                            t.remove(k);
                            continue;
                        }
                        int jt = Integer.parseInt(v.substring(v.lastIndexOf(",")+1,v.lastIndexOf(")")));
                        if(j - jt > 2){
                            t.remove(k);
                            continue;
                        }
                    }
                    t.set(k, t.get(k) + x.charAt(i)+"("+i+","+j+")");
                }
            }else if(c[i][j] == 2){
                t = getLCS(c,i-1,j,x,y);
            }else if(c[i][j] == 3){
                t.addAll(getLCS(c,i-1,j,x,y));
                t.addAll(getLCS(c,i,j-1,x,y));
            }else{
                t = getLCS(c,i,j-1,x,y);
            }
            return t;
        }
        
        public static int LCSLength(int[][] c, int i, int j, byte[] xx, byte[] yy,int[][] max){
            
            if(i == 0 || j == 0){
                c[i][j] = 0;
            }else if(xx[i] == yy[j]){
                max[i][j] = 1;    
                c[i][j] = LCSLength(c,i-1,j-1,xx,yy,max)+1;
            }else {
                int ii = LCSLength(c,i-1,j,xx,yy,max);
                int jj = LCSLength(c,i,j-1,xx,yy,max);
                if(ii > jj)
                    max[i][j] = 2;
                else if(ii == jj)
                    max[i][j] = 3;
                    
                c[i][j] = Math.max(ii,jj);
            }
            return c[i][j];
        }
        
        
        public static void main(String[] args){
            String x = " ABCBDAB";
            String y = " BDCABA";
            
            byte[] xx = x.getBytes();
            byte[] yy = y.getBytes();
            
            int c[][] = new int[x.length()][y.length()];
            int max[][] = new int[x.length()][y.length()];
            System.out.println(LCSLength(c,x.length()-1,y.length()-1,xx,yy,max));
            
            List<String> list  = getLCS(max,x.length()-1,y.length()-1,x,y);
            for(String v: list)
                System.out.println(v);
            System.out.print("
      ");
            for(int j = 1; j < y.length();j++)
                System.out.print(y.charAt(j)+ " ");
            System.out.println("");
            for(int i = 1; i < x.length(); i++){
                System.out.print(x.charAt(i)+ " ");
                for(int j = 1; j < y.length();j++)
                    System.out.print(c[i][j]+ " ");
                System.out.println(" ");
            }
            
        }
    }
  • 相关阅读:
    dd
    VIC流程
    哈哈
    骂人的话 越毒越好不带脏字
    经典笑话大全 一句话超经典
    Struts,Hibernate,Spring经典面试题收藏
    尚学堂java相关
    Java关键字final、static使用总结
    新买了一对充电电池,是该先用光电再充还是先充再用?
    华为boss力荐公司高层看的一篇文章,真的很经典!!![转载]
  • 原文地址:https://www.cnblogs.com/dorothychai/p/4609113.html
Copyright © 2020-2023  润新知