您的位置:首页 > 其它

最长公共子序列LCS

2016-09-14 23:38 204 查看
package DynamicProgram;

import org.junit.Test;

public class LCS {

// 输入两个序列,求最长公共子序列
// b和c两个数组一个用来保存计算结果,一个用来保存路径
// 数组b中用1表示左上方,2表示上方,3表示左方
public void LcsLength(int [] rows, int [] cols, int [] [] b, int [] [] c) {
int rowsLength = rows.length;
int colsLength = cols.length;
for (int i = 1; i < rowsLength; ++i) {
for (int j = 1; j < colsLength; ++j) {
if (rows[i] == cols[j]) {
c[i][j] = c[i-1][j-1] + 1;
b[i][j] = 1;
}
else if (c[i][j - 1] > c[i - 1][j]) {
c[i][j] = c[i][j - 1];
b[i][j] = 2;
}
else {
c[i][j] = c[i - 1][j];
b[i][j] = 3;
}
}
}
}

public void printLcs(int [] [] b, int [] rows, int i, int j) {
if (i == 0 || j == 0) {
return;
}
if (b[i][j] == 1) {
System.out.println((char) rows[i]);
printLcs(b, rows, i - 1, j - 1);
}
else if (b[i][j] == 2) {
printLcs(b, rows, i, j - 1);
}
else
printLcs(b, rows, i - 1, j);

}

@Test
public void test() {
// 下标为0的索引值暂时不用
int [] cols = {-1, 'A', 'B', 'C', 'B', 'D', 'A', 'B'};
int [] rows = {-1, 'B', 'D', 'C', 'A', 'B', 'A'};
// 准备工作
// 其实算法的空间复杂度可以进一步的优化
int rowsLength = rows.length;
int colsLength = cols.length;
// 声明两个m行n列的数组,这里是因为数组的下标0没有使用,否则的话需要数组的长度+1
// 用来记录一些额外的路径信息
int [][] path = new int [rowsLength][colsLength];
// 用来记录子问题,即最长子序列的长度
int [][] len = new int [rowsLength][colsLength];
for (int j = 0; j < rowsLength; ++j)
len[j][0] = 0;
for (int i = 0; i < colsLength; ++i)
len[0][i] = 0;
LcsLength(rows, cols, path, len);
//System.out.println(len[rowsLength - 1][colsLength - 1]);
// 注意这个打印出来的一个最优LCS的反序输出
printLcs(path, rows, rowsLength - 1, colsLength - 1);
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: