计算回文子序列(Java语言,动态规划,递归)
2016-06-15 18:04
555 查看
LCS是指最长公共子序列。计算2个字符串的LCS的算法,被广泛应用于搜索引擎,文本编辑器,文本比较工具,IDE等工具中。
LCS计算基于已经证明的一种递推关系。即:
1.当Xm == Yn时,LCS(X(m),Y(n)) = LCS(X(m-1),Y(n-1)) + Xm
2.当Xm != Yn时,LCS(X(m),Y(n)) = max( LCS(X(m-1),Y(n)), LCS(X(m),Y(n-1))
基于以上递推关系则可以推导出LCS算法的基本要领:
1.基于递推关系计算出LCS的长度矩阵和方向矩阵.
2.基于方向矩阵则可计算任意的X(m)序列和Y(n)序列的LCS。
什么是方向矩阵?
简言之,方向矩阵记录了给定的m与n,LCS(X(m),Y(n))的计算方法。有了这个矩阵,我们就知道,LCS(X(m),Y(n))是应该转化成上述推导式中的哪一种情况。显然,方向矩阵共有3种方向。
LCS计算基于已经证明的一种递推关系。即:
1.当Xm == Yn时,LCS(X(m),Y(n)) = LCS(X(m-1),Y(n-1)) + Xm
2.当Xm != Yn时,LCS(X(m),Y(n)) = max( LCS(X(m-1),Y(n)), LCS(X(m),Y(n-1))
基于以上递推关系则可以推导出LCS算法的基本要领:
1.基于递推关系计算出LCS的长度矩阵和方向矩阵.
2.基于方向矩阵则可计算任意的X(m)序列和Y(n)序列的LCS。
什么是方向矩阵?
简言之,方向矩阵记录了给定的m与n,LCS(X(m),Y(n))的计算方法。有了这个矩阵,我们就知道,LCS(X(m),Y(n))是应该转化成上述推导式中的哪一种情况。显然,方向矩阵共有3种方向。
import java.io.*; class test { public static void main (String[] args) throws java.lang.Exception { char x[] = "abcdefaacff".toCharArray(); char y[] = "abdfeaacaa".toCharArray(); getStringsLCS(x,y); } public static int getStringsLCS(char []x, char[] y) { int m = x.length; int n = y.length; int [][] c = new int[m + 1][n + 1]; int [][] b = new int[m + 1][n + 1]; for(int i = 0;i <= m; i++) { c[i][0] = 0; } for(int i = 0;i <= n; i++) { c[0][i] = 0; } for(int i = 0;i < m; i++) { for(int j = 0;j < n; j++) { if(x[i] == y[j]) { c[i + 1][j + 1] = c[i][j] + 1; b[i + 1][j + 1] = 0; } else if(c[i + 1][j] >= c[i][j + 1]) { c[i + 1][j + 1] = c[i + 1][j]; b[i + 1][j + 1] = 1; } else { c[i + 1][j + 1] = c[i][j + 1]; b[i + 1][j + 1] = 2; } } } //printArray2D(b); StringBuilder sb = outputStringsLCS(b,x,m,n); System.out.print(sb); return 0; } static void printArray2D(int[][] c) { for(int i = 0;i < c.length;i ++) { for(int j = 0;j < c[0].length;j ++) { System.out.print(c[i][j]); } System.out.println(""); } } static StringBuilder outputStringsLCS(int[][] b,char[] x, int i, int j) { if(i == 0 || j == 0) { return new StringBuilder(); } StringBuilder sb; if(b[i][j] == 0) { sb = outputStringsLCS(b, x, i - 1, j - 1); sb.append(x[i - 1]); } else if(b[i][j] == 1) { return outputStringsLCS(b, x, i, j - 1); } else { return outputStringsLCS(b, x, i - 1, j); } return sb; } }
相关文章推荐
- 书评:《算法之美( Algorithms to Live By )》
- 动易2006序列号破解算法公布
- C#递归算法之分而治之策略
- Ruby实现的矩阵连乘算法
- C#插入法排序算法实例分析
- 超大数据量存储常用数据库分表分库算法总结
- C#数据结构与算法揭秘二
- C#冒泡法排序算法实例分析
- 算法练习之从String.indexOf的模拟实现开始
- C#算法之关于大牛生小牛的问题
- C#实现的算24点游戏算法实例分析
- 经典排序算法之冒泡排序(Bubble sort)代码
- c语言实现的带通配符匹配算法
- 浅析STL中的常用算法
- 算法之排列算法与组合算法详解
- C++实现一维向量旋转算法
- Ruby实现的合并排序算法
- C#折半插入排序算法实现方法
- 基于C++实现的各种内部排序算法汇总
- C++线性时间的排序算法分析