【问题标题】:Longest common subsequence optimized最长公共子序列优化
【发布时间】:2015-04-22 16:04:22
【问题描述】:

我目前正在尝试查找并打印 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];
        }
    }
}

【问题讨论】:

标签: c++ algorithm optimization longest-substring


【解决方案1】:

似乎没有简单的方法可以完成,因为如果只保留最后两列,就会丢失重要的部分信息。

例如,考虑两种情况:(abccacc)字符串和(abccbcc)字符串。这些情况的矩阵将是

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

您会看到最后两列在两种情况下都是相同的,因此您不会仅通过最后两列来区分这些情况。但是你需要区分它们,因为答案是不同的(accbcc)。当然,您仍然拥有原始字符串并且可以使用那里的信息,但我认为(尽管我没有证明这一点)这或多或少等同于为原始字符串的某些前缀找到 LCS。

同时,还有a more advanced algorith在二次时间和线性空间中工作。

【讨论】:

  • 虽然我正在处理行,并且在您的示例中 accbcc 有不同的最后 2 行,但我知道在某些情况下它是相同的。 Hitschberg 算法可以,但我想我会留在整张桌子上。感谢您的帮助!
猜你喜欢
  • 2014-11-08
  • 1970-01-01
  • 2011-03-01
  • 2011-02-25
  • 2013-02-13
  • 1970-01-01
  • 2014-07-23
  • 1970-01-01
相关资源
最近更新 更多