您的位置:首页 > 编程语言 > Java开发

计算回文子序列(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种方向。

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;
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  算法