问题描述:
给定序列 X 与 Y,若 Z 既是 X 的子序列,又是 Y 的子序列,则成 Z 为 X 和 Y 的公共子序列。Z中包含元素最多的子序列就是最大公共子序列。
比如:X={A,B,C,B,D,A,B},Y ={C,B,C,E,D,B},则{B,C,D,B}是最大公共子序列。
任意两个字符串 X 与 Y 的最大公共子序列的求法:
利用动态规划法:
代码实现:
/** * 最长公共子序列 * seq1:第一个序列 * seq2:第二个序列 * */ public int LongComSubSeq(int[] seq1,int[] seq2){ if(seq1==null||seq1.length==0||seq2==null||seq2.length==0){ return -1; } int len1 = seq1.length+1; int len2 = seq2.length+1; //存放公共子串的长度 int[][] LCSLen = new int[len1][len2]; //存放 int[][] LCSDrec = new int[len1][len2]; //接下来三个循环为初始化 for(int i=0;i<len1;i++){ LCSLen[i][0] = 0; } for(int j=0;j<len2;j++){ LCSLen[0][j] = 0; } for(int i=0;i<len1;i++){ for(int j=0;j<len2;j++){ LCSDrec[i][j] =0; } } for(int i=1;i<len1;i++){ for(int j=1;j<len2;j++){ if(seq1[i-1] == seq2[j-1]){ //System.out.println("序列值seq1:"+seq1[i-1]); // System.out.println("序列值seq2:"+seq2[j-1]); LCSLen[i][j] = LCSLen[i-1][j-1]+1; // System.out.println("序列长度:"+LCSLen[i][j]); LCSDrec[i][j] = 1; }else if(LCSLen[i-1][j]>LCSLen[i][j-1]){ LCSLen[i][j] = LCSLen[i-1][j]; LCSDrec[i][j] = 2; }else { LCSLen[i][j] =LCSLen[i][j-1]; LCSDrec[i][j] = 3; } } } LCSPrint(LCSDrec,seq1,len1-1,len2-1); return LCSLen[len1-1][len2-1]; } //最长公共子序列输出函数 public void LCSPrint(int[][] LCSDrec,int[] seq1,int len1,int len2){ if(LCSDrec==null||seq1==null||len1<=0||len2<=0){ return; } if(LCSDrec[len1][len2]==1){ System.out.println(" "+seq1[len1-1]); LCSPrint(LCSDrec,seq1,len1-1,len2-1); }else if(LCSDrec[len1][len2]==2){ LCSPrint(LCSDrec,seq1,len1-1,len2); }else{ LCSPrint(LCSDrec,seq1,len1,len2-1); } }