zoukankan      html  css  js  c++  java
  • 最长公共子序列(LCS)

    最长公共子序列问题在算法导论中引申自确定DNA序列相似度的问题:给定两个DNA序列S1和S2,寻找第三个序列S3,要求序列S3中的元素都来源于S1和S2,且在这三个序列中先后顺序相同,但在S1和S2中不要求连续,如果找到这样的S3序列越长,可以认为S1和S2相似度越高。

    问题描述:

    给定两个序列X=<x1,x2,x3...xm>和序列Y=<y1,y2,y3...yn>,求X和Y的最长公共子序列(LCS)。

    分析:

    分析其最优子结构性质需要从xm和yn入手,假设序列Z=<z1,z2,z3...zk>是序列X和Y的LCS

    1、如果xm=yn,说明这两个元素(实际上为同一个)必然在Z中,由于这两个元素同时最为X和Y的最后一个元素,不难推断,xm=yn=zk必然成立,从Z中排除掉zk剩下的序列Zk-1=<z1,z2,z3...zk-1>必然是Xm-1和Yn-1的一个LCS。

    2、如果xm!=yn,且zk!=xm,那么xm必定不在Z中,但是yn有可能在Z中,因此可以判定,Z是Xm-1和Y的一个LCS。

    3、如果xm!=yn,且zk!=yn,那么yn必定不在Z中,但是xm有可能在Z中,因此可以判定,Z是X和Yn-1的一个LCS。

     用C(i,j)表述Xi和Yi的LCS,其递推式可以表示为:

    实际上可以看出对于每一个子问题C(i,j)的求解,不会用到太多的子子问题的解,字需要用到C(i-1,j-1)的解或者C(i-1,j)和C(i,j-1)的解。

    也就是说求解当前表格的值只有其左方表格,上方表格和左上方的表格有关。

    因此填充C(i,j)二维表格的顺序应该是从左到右,从上到下的顺序,这也是求解子问题的顺序。

    算法实现:

    package agdp;
    
    import java.util.Arrays;
    public class LCS {
        public static int getLCS(String strA,String strB){
            int m = strA.length();
            int n = strB.length();
            int[][] aux = new int[m+1][n+1];//aux的第0行和第0列充当哨兵,无实际含义
            for (int i = 0; i < m; i++) {
                for (int j = 0; j < n; j++) {
                    if (strB.charAt(j) == strA.charAt(i)) {
                        aux[i+1][j+1] = aux[i][j]+1;
                    }else {
                        aux[i+1][j+1] = Math.max(aux[i+1][j], aux[i][j+1]);
                    }
                }
            }
            return aux[m][n];
        }
        public static void main(String[] args) {
            // TODO Auto-generated method stub
    //        String strA = "ABCBDAB";
    //        String strB = "BDCABA";
            String strA = "abfgkhrc";
            String strB = "11a11bfgh33";
            int result = getLCS(strA, strB);
            System.out.println(result);
        }
    
    }

    参考资料:

    算法导论.第十五章

  • 相关阅读:
    设计模式第一次练习
    区间最大数
    魔方数
    螺旋数
    回文串
    最长单词
    指针的应用之学生成绩
    赛马
    突击队任务
    贪婪之骑士
  • 原文地址:https://www.cnblogs.com/qcblog/p/7784625.html
Copyright © 2011-2022 走看看