最长公共子序列优化
Longest common subsequence optimized
我目前正在尝试查找并打印 2 个给定字符串的最长公共子序列。我使用没有递归的最常见算法。如果我保留整个数组,这是一个简单的任务,但我正在尝试对其进行一些优化并仅使用 2 行,您可以在下面的代码中看到。通过此更改,查找长度仍然很简单并且工作正常,但恢复子序列不再那么容易了。我试过几种方法,但都没有用。下面你可以看到我最后的尝试。虽然它适用于相同的情况,但也有失败的情况。经过长时间的思考,我开始相信没有办法使用只有 2 行的数组来恢复子序列。我的研究没有给我带来确切的答案,所以我想问是否有办法实现我想要做的事情?或者如果我想打印,我是否坚持保留整个数组?
//finding length of longest common subsequence
for(int i=1; i<m; i++) {
for(int j=1; j<n; j++) {
if(sequece1[i-1] == sequence2[j-1]) {
tab[i%2][j] = tab[(i-1)%2][j-1] + 1;
} else {
tab[i%2][j] = max(tab[i%2][j-1],tab[(i-1)%2][j]);
}
}
}
//trying to reconstruct longest common subsequence
int last_row = (m-1)%2;
for(int j=n-1; j>0; j--) {
if(tab[last_row][j-1] < tab[last_row][j]) {
if(last_row == 0) {
common_part += sequence2[j];
} else {
common_part += sequence2[j-1];
}
}
}
似乎没有简单的方法可以完成,因为如果你只保留最后两列,信息的重要部分就会丢失。
例如,考虑两种情况:(abcc
, acc
) 字符串和 (abcc
, bcc
) 字符串。这些案例的矩阵将是
1 1 1 1 and 0 1 1 1
1 1 2 2 0 1 2 2
1 1 2 3 0 1 2 3
你看到最后两列在两种情况下是相同的,所以你不会仅通过最后两列来判断这些情况。但是你需要区分它们,因为答案是不同的(acc
和 bcc
)。当然,您仍然拥有原始字符串并可以使用那里的信息,但我认为(虽然我没有证明这一点)这或多或少等同于为原始字符串的某些前缀找到 LCS。
同时还有a more advanced algorith以二次时间和线性方式工作space。
我目前正在尝试查找并打印 2 个给定字符串的最长公共子序列。我使用没有递归的最常见算法。如果我保留整个数组,这是一个简单的任务,但我正在尝试对其进行一些优化并仅使用 2 行,您可以在下面的代码中看到。通过此更改,查找长度仍然很简单并且工作正常,但恢复子序列不再那么容易了。我试过几种方法,但都没有用。下面你可以看到我最后的尝试。虽然它适用于相同的情况,但也有失败的情况。经过长时间的思考,我开始相信没有办法使用只有 2 行的数组来恢复子序列。我的研究没有给我带来确切的答案,所以我想问是否有办法实现我想要做的事情?或者如果我想打印,我是否坚持保留整个数组?
//finding length of longest common subsequence
for(int i=1; i<m; i++) {
for(int j=1; j<n; j++) {
if(sequece1[i-1] == sequence2[j-1]) {
tab[i%2][j] = tab[(i-1)%2][j-1] + 1;
} else {
tab[i%2][j] = max(tab[i%2][j-1],tab[(i-1)%2][j]);
}
}
}
//trying to reconstruct longest common subsequence
int last_row = (m-1)%2;
for(int j=n-1; j>0; j--) {
if(tab[last_row][j-1] < tab[last_row][j]) {
if(last_row == 0) {
common_part += sequence2[j];
} else {
common_part += sequence2[j-1];
}
}
}
似乎没有简单的方法可以完成,因为如果你只保留最后两列,信息的重要部分就会丢失。
例如,考虑两种情况:(abcc
, acc
) 字符串和 (abcc
, bcc
) 字符串。这些案例的矩阵将是
1 1 1 1 and 0 1 1 1
1 1 2 2 0 1 2 2
1 1 2 3 0 1 2 3
你看到最后两列在两种情况下是相同的,所以你不会仅通过最后两列来判断这些情况。但是你需要区分它们,因为答案是不同的(acc
和 bcc
)。当然,您仍然拥有原始字符串并可以使用那里的信息,但我认为(虽然我没有证明这一点)这或多或少等同于为原始字符串的某些前缀找到 LCS。
同时还有a more advanced algorith以二次时间和线性方式工作space。