最长公共子序列问题(Longest common subsequence,LCS)
来源:互联网 发布:帝国cms表单反馈邮箱 编辑:程序博客网 时间:2024/05/16 07:17
参考屈婉玲的youtube视频:https://www.youtube.com/watch?v=zkCHuCCoQEY
参考:《算法导论》P390页15.4 Longest common subsequence
问题描述:序列X={x1,x2,…,xn},Y={y1,y2,…,yn},当Z={z1,z2…,zn}是X的严格递增下标顺序(可以不连续)的子集,也是Y的严格递增下标顺序(可以不连续)的子集,则Z是X和Y的公共子序列。例如X={A,B,C,B,D,A,B},Y={B,D,C,A,B,A},{B,C,A}、{B,C,B,A}、{B,D,A,B}都是X和Y的公共子序列。其中最长的公共子序列叫做Longest common subsequence,即经典的LCS。
具体点:char[]xArray和char[] yArray是字符数组,长度分别为m、n,求他们的LCS
【分析】自顶向下分析,二维数组cTable[i][j]记录xArray[0~i],yArray[0~j]的最长公共子序列的长度,则cTable[m][n]记录xArray[0~m],yArray[0~n]的最长公共子序列的长度。
1) 如果xArray[m]=yArray[n],表明最后一个元素xArray[m]是LCS中的元素,xArray[0~m],yArray[0~n]的最长公共子序列=xArray[0~m-1],yArray[0~n-1]的最长公共子序列+1,即cTable[m][n]=cTable[m-1][n-1]。
2) 如果xArray[m]!=yArray[n],表明xArray[m]、yArray[n]都有可能是LCS中的元素,但不能同时是。如果xArray[m]可能是,则xArray[0~m],yArray[0~n]的最长公共子序列=xArray[0~m],yArray[0~n-1]的最长公共子序列;如果yArray[n]可能是,则xArray[0~m],yArray[0~n]的最长公共子序列=xArray[0~m-1],yArray[0~n]的最长公共子序列。即cTable[m][n]=max(cTable[m-1][n], cTable[m][n-1])。
状态递归方程为:
参考《算法导论》P394页伪代码,java实现如下:
*****************************************
控制台输出:
最大子数组为:BCBACBACB
长度为:9
--------------------------------------------------------------------------------------------------------
或者以下写法
class Untitled { public static void main(String[] args) { // TODO 自动生成的方法存根 String x="ABCBDABCBACABC"; String y="BDCABACABABCB"; int temp=getLCSLength(x, y); System.out.println("\n长度为:"+temp); } public static int getLCSLength(String x,String y) { char[] xArray=x.toCharArray(); char[] yArray=y.toCharArray(); int m=xArray.length; int n=yArray.length; int [][] bTable=new int[m][n]; /*cTable[i][j]记录xArray[0~i],yArray[0~j]的最长公共子序列的长度*/ int [][] cTable=new int[m+1][n+1]; for (int i = 0; i <=m; i++) { for (int j = 0; j <=n; j++) { if(i==0||j==0){ cTable[i][j]=0;}else{ if (xArray[i-1]==yArray[j-1]) { cTable[i][j]=cTable[i-1][j-1]+1; bTable[i-1][j-1]=2;//相等标记为2 }else if (cTable[i-1][j]>=cTable[i][j-1]) { cTable[i][j]=cTable[i-1][j]; bTable[i-1][j-1]=1; }else { cTable[i][j]=cTable[i][j-1]; bTable[i-1][j-1]=3; } } } } System.out.print("最大子数组为:"); printLCS(xArray, bTable, m-1,n-1); return cTable[m][n]; } /*输出最佳路径即最长公共子序列*/ public static void printLCS (char[] xArray,int[][] bTable,int i,int j) { if (i==-1||j==-1) { return; } if (bTable[i][j]==2) { printLCS(xArray, bTable, i-1, j-1); System.out.print(xArray[i]); }else if (bTable[i][j]==1) { printLCS(xArray, bTable, i-1, j); }else { printLCS(xArray, bTable, i, j-1); } } }
通过java在线运行环境http://run.jser.com/java.html
执行结果
最大子数组为:BCBACBACB
长度为:9
/**
* @param A, B: Two strings.
* @return: The length of longest common subsequence of A and B.
*/
public int longestCommonSubsequence(String A, String B) {
// write your code here
if (A == null || B == null) {
return 0;
}
int lenA = A.length();
int lenB = B.length();
int[][] D = new int[lenA + 1][lenB + 1];
for (int i = 0; i <= lenA; i++) {
for (int j = 0; j <= lenB; j++) {
if (i == 0 || j == 0) {
D[i][j] = 0;
} else {
if (A.charAt(i - 1) == B.charAt(j - 1)) {
D[i][j] = D[i - 1][j - 1] + 1;
} else {
D[i][j] = Math.max(D[i - 1][j], D[i][j - 1]);
}
}
}
}
return D[lenA][lenB]; //D[lenA][lenB]代表最长公共子序列的长度。
}
}
- 最长公共子序列问题(LCS) Longest common subsequence
- 最长公共子序列问题(Longest common subsequence,LCS)
- 最长公共子序列问题LCS Longest Common Subsequence
- 最长公共子序列问题(LCS, Longest Common Subsequence)
- 最长公共子序列(Longest Common Subsequence LCS)
- 最长公共子序列(Longest-Common-Subsequence,LCS)
- uva10405 - Longest Common Subsequence(LCS,最长公共子序列)
- 最长公共子序列LCS(The longest common subsequence)
- LCS(Longest Common Subsequence 最长公共子序列)
- 最长公共子序列与最长公共子串(Longest Common Subsequence, LCS)
- uva 10405 Longest Common Subsequence 最长公共子序列 LCS
- 最长公共子序列(LCS, Longest Common Subsequence), POJ 1458
- 求最长公共子序列Longest Common Subsequence LCS
- 最长公共子序列(Longest Common Subsequence, LCS)
- 最长公共子序列(Longest Common Subsequence,LCS)
- 最长公共子序列,Longest-Common-Subsequence(LCS)
- 动态规划解最长公共子序列问题LCS(longest common subsequence)
- 【算法导论学习-29】动态规划经典问题02:最长公共子序列问题(Longest common subsequence,LCS)
- debug assertion failed问题
- js获取日期
- Bootstrap日历DateTime Picker控件简单应用
- 简单了解Handler
- 系列:iOS开发-NSString
- 最长公共子序列问题(Longest common subsequence,LCS)
- Feign介绍
- jdk深入了解
- Windows 下openssl安装与配置
- 第一篇博客
- 浅谈数通畅联ECP与EAC的区别
- eclipse导入MyEclipse web项目无法识别的问题解决
- 递推递归练习 A 母牛的故事
- 我所理解的AsyncTask