注意:我事先进行了搜索,但找不到解决所有子序列的LCS问题的建议。
我在编写“最长公共子序列”问题的解决方案时遇到了麻烦,在这个问题中,我返回了两个输入字符串的所有最长公共子序列。我查看了Wikipedia page,并试图在其中实现伪代码,但我的"backtrackAll“方法遇到了问题。我相信我下面计算的LCS矩阵是正确的,但是我的"backtrackAll“方法返回一个空集。对我做错了什么有什么建议吗?
public static void main (String[] args) {
String s1 = "AGCAT";
String s2 = "GAC";
int[][] matrix = computeMatrix(s1,s2);
HashSet<String> set = backtrackAll(matrix,s1,s2,s1.length(),s2.length());
//more stuff would go here...
}
private static int[][] computeMatrix(String s1, String s2) {
int[][] C = new int[s1.length()+1][s2.length()+1];
for (int i = 1; i < s1.length()+1; i++) {
for (int j = 1; j < s2.length()+1; j++) {
if (s1.charAt(i-1) == s2.charAt(j-1)) {
C[i][j] = C[i-1][j-1] + 1;
} else {
C[i][j] = Math.max(C[i][j-1], C[i-1][j]);
}
}
}
return C;
}
private static HashSet<String> backtrackAll(int[][] C, String s1, String s2, int i, int j) {
if (i == 0 || j == 0) {
return new HashSet<String>();
} else if (s1.charAt(i-1) == s2.charAt(j-1)) {
HashSet<String> R = backtrackAll(C,s1,s2,i-1,j-1);
HashSet<String> new_set = new HashSet<String>();
for (String Z: R) {
new_set.add(Z + s1.charAt(i-1));
}
return new_set;
} else {
HashSet<String> R = new HashSet<String>();
if (C[i][j-1] >= C[i-1][j]) {
R = backtrackAll(C, s1, s2, i, j-1);
}
if (C[i-1][j] >= C[i][j-1]) {
R.addAll(backtrackAll(C,s1,s2,i-1,j));
}
return R;
}
}发布于 2012-01-25 04:22:07
我对它做了一点修改。它现在可以工作了。您还应该考虑何时返回空的HashSet,在这种情况下必须添加最后一个匹配的字符。
private static HashSet<String> backtrackAll(int[][] C, String s1, String s2, int i, int j) {
// System.out.println(i+" " + j);
if (i == 0 || j == 0) {
// System.out.println("0t");
return new HashSet<String>();
} else if (s1.charAt(i - 1) == s2.charAt(j - 1)) {
// System.out.println("2t");
HashSet<String> R = backtrackAll(C, s1, s2, i - 1, j - 1);
HashSet<String> new_set = new HashSet<String>();
for (String Z : R) {
// System.out.println("1t");
new_set.add(Z + s1.charAt(i - 1));
}
new_set.add("" + s1.charAt(i - 1));
return new_set;
} else {
// System.out.println("3t");
HashSet<String> R = new HashSet<String>();
if (C[i][j - 1] >= C[i - 1][j]) {
R = backtrackAll(C, s1, s2, i, j - 1);
}
if (C[i - 1][j] >= C[i][j - 1]) {
R.addAll(backtrackAll(C, s1, s2, i - 1, j));
}
return R;
}
}发布于 2011-09-10 09:54:06
既然这是“作业”,这里有几个小贴士。
assert语句,以检查你认为应该成立的前置条件、后置条件和不变量。(按照标准的java -ea ...)发布于 2013-04-09 17:44:38
第二个答案打印了所有内容,但不仅仅是最长的,我的答案是正确的。
private static HashSet<String> backtrackAll(int[][] C, String s1, String s2, int i, int j) {
if (i == 0 || j == 0) {
HashSet<String> set = new HashSet<String>();
set.add("");
return set;
} else if (s1.charAt(i - 1) == s2.charAt(j - 1)) {
HashSet<String> R = backtrackAll(C, s1, s2, i - 1, j - 1);
HashSet<String> new_set = new HashSet<String>();
for (String Z : R) {
new_set.add(Z + s1.charAt(i - 1));
}
return new_set;
} else {
HashSet<String> R = new HashSet<String>();
if (C[i][j - 1] >= C[i - 1][j]) {
R = backtrackAll(C, s1, s2, i, j - 1);
}
if (C[i - 1][j] >= C[i][j - 1]) {
R.addAll(backtrackAll(C, s1, s2, i - 1, j));
}
return R;
}
}https://stackoverflow.com/questions/7369025
复制相似问题