算法——动态规划篇——最长公共子序列
来源:互联网 发布:mysql 5.5.37 for mac 编辑:程序博客网 时间:2024/06/10 21:20
问题描述
最长公共子序列,英文缩写为LCS(Longest Common Subsequence)。其定义是,一个序列 S ,如果分别是两个或多个已知序列的子序列,且是所有符合此条件序列中最长的,则 S 称为已知序列的最长公共子序列。
解决最长公共子序列,一种常用的办法,就是穷举法,组合出所有的情况,但是这样对于长序列的情况来说,是非常不实际。。
假设现在有两个序列,x[]={'A','B','C','B','D','A','B'};y[]={'B','D','C','A','B','A'};
如果采用穷举的方式,会是以下情况
x:A,B,C,B,D,A,B
y:B,D,C,A,B,A
A与B比较,一直到A与Y中出现的第一个A遇到事停止(红色部分),然后再从X序列中的B与Y中B开始比较,(绿色部分),接着这样下去,直观上看,执行这一次遍历,就是n*n的代价,要是把所有的可能都遍历一下,代价太大了。。
只有采用其他的方法了,
动态规划:
观察到序列求解过程中,有一定的相似度,比如说,如果我们的序列是X:A,B,C;Y:B,D,C;由于Xc=Yc,所有要往前面的两个元素看,也就是比较X:A,B;Y:B,D,由于Xb!=Yd,那么我们需要判断X:A;Y:B,D的最大序列,以及X:A,B;YB的最大序列,取两者中最大的一个,保留下来,作为X:A,B;Y:B,D的最大序列值。
分析问题的时候一直要先从整体上来把握,体会他的整体局部的相关性,而不是孤立出来,只是单纯的从元素本身来判断,那样就不好明白问题的规律。。。
最后还是翻看了算法导论,才明白这一点,没有把握住,问题的本质。。
最长子序列的规律:
c[i][j]={
0 ,i=0||j=0
c[i-1][j-1]+1 ,i,j>0&&xi=yj
max(c[i-1][j],c[i][j-1]),i,j>0&&xi!=yj
}
分析清楚问题真的很重要。。。。把握问题的本质。。。
代码如下:
package hello.ant;//最长公共子序列public class AlogLCS {public static void main(String[] args) {char x[]={'A','B','C','B','D','A','B'};char y[]={'B','D','C','A','B','A'};int c[][]=new int[x.length+1][y.length+1];////////////// ^|^ ~~ ~~~///////////// | ~ ------- ~~~////////////// | ~~ ~~////////////// 用0表示向上 1向左 2表示斜向左上int flag[][]=new int[x.length+1][y.length+1];//用来控制打印的方向//初始化for(int i=0;i<y.length+1;i++){c[0][i]=0;}for(int i=0;i<x.length+1;i++){c[i][0]=0;}for(int i=1;i<x.length+1;i++){for(int j=1;j<y.length+1;j++){if(x[i-1]==y[j-1]){c[i][j]=c[i-1][j-1]+1;flag[i][j]=2;}else {if(c[i-1][j]>=c[i][j-1]){c[i][j]=c[i-1][j];flag[i][j]=0;}else {c[i][j]=c[i][j-1];flag[i][j]=1;}}}}StringBuilder result=new StringBuilder();display(x,flag,x.length,y.length,result);System.out.println("\n*********");System.out.println(result.reverse().toString());}static void display(char[] x, int[][] flag, int i, int j,StringBuilder result) {if(i==0||j==0){return;}if(flag[i][j]==2){System.out.print(x[i-1]+" ");result.append(x[i-1]);display(x, flag, i-1, j-1,result);}else if(flag[i][j]==1){display(x, flag, i, j-1,result);}else if(flag[i][j]==0){display(x, flag, i-1, j,result);}}}
结果如下:
A B C B
*********
BCBA
红色部分才是真正的最长子序列。。。
- 动态规划算法——最长公共子序列求法
- 算法——动态规划篇——最长公共子序列
- 算法12—动态规划算法之:最长公共子序列 & 最长公共子串(LCS)
- 动态规划——最长公共子序列
- 动态规划——最长公共子序列(LCS)
- 动态规划——最长公共子序列(LCS)
- 最长公共子序列问题——动态规划
- 动态规划——最长公共子序列问题
- 动态规划——最长公共子序列
- 动态规划——最长公共子序列
- 动态规划——最长公共子序列
- 最长公共子序列问题—— 动态规划法
- 动态规划——最长公共子序列问题
- 动态规划法——最长公共子序列问题
- 动态规划——最长公共子序列总结
- 动态规划——最长公共子序列
- 动态规划——最长公共子序列计算
- 动态规划——最长公共子序列问题(LCS)
- 帆软与用友:共建安徽国资委财务信息系统
- [leetcode]Minimum Window Substring
- POJ 1047——解题报告
- vs如何向main函数传参数、设置字符编码、设置OpenMp等
- 使用lint提高android代码质量
- 算法——动态规划篇——最长公共子序列
- 九度 题目1366:栈的压入、弹出序列
- java多线程
- 用maven导出依赖jar
- ios上ZXing库的配置流程
- pool is already maxed out. [managed: 15; max: 15]
- NetBeans 7.2 or 8.0 编辑文件时不显示文件路径。
- 如何制作Cognos Mobile上面Active Report
- json_decode 转换json对象为数组需注意true 你加了吗?