最长公共子序列

来源:互联网 发布:转运公司知乎 编辑:程序博客网 时间:2024/06/01 19:02

1.问题描述:求两个字符数组的最长公共子序列,子序列可以是不连续的,也就是一个长度为n的字符数组可以有2n个子序列。
2.数学分析:设字符数组A[a1,a2,a3...,am],B[b1,b2,b3...bn]
如果am = bn,那么最长公共子序列的长度为[a1,a2,a3...,am1][b1,b2,b3...bn1]的最长公共子序列加1,如果am!=bn,那么最长公共子序列的长度就应该在[a1,a2,a3...,am][b1,b2,b3...bn1][a1,a2,a3...,am1][b1,b2,b3...bn]的最长公共子序列长度中取最大值。
那么设二维数组C[m][n]来记录A、B所有子序列的公共子序列长度,然后再通过回溯来得到公共子序列。有公式:

C[i][j]=0C[m1][n1]+1max{C[m1][n],C[m][n1]}i=0orj=0,ai=bj,ai!=bj,

3.实现代码:

public class LCS{    static String[] a = { "B", "D", "C", "A", "B", "A" };    static String[] b = { "A", "B", "C", "B", "D", "A", "B" };    static int[][] c = new int[a.length + 1][b.length + 1];    static Stack<String> s = new Stack<String>();    public static void main(String args[]){        for(int i = 1, j = a.length; i <= j; i++){            for(int k = 1, l = b.length; k <= l; k++){                if(a[i-1].equals(b[k-1]))                    c[i][k] = c[i-1][k-1] + 1;                else                    c[i][k] = (c[i][k-1] > c[i-1][k]) ? c[i][k-1] : c[i-1][k];            }        }       }//打印LCS,但是只能打印出一条LCS,打印全部LCS有空再补上    private static void printLcs(int ai, int bi){        if(ai == 0 || bi ==0)            return;        else if(a[ai-1].equals(b[bi-1])){            System.out.print(a[ai-1]);            printLcs(ai-1, bi-1);        }        else if(c[ai][bi-1] == c[ai][bi])            printLcs(ai, bi-1);        else            printLcs(ai-1, bi);    }}
0 0
原创粉丝点击