我认为我已经从this page充分掌握了LCS算法。特别是这个psedo-code实现:(m和n是A和B的长度)
int lcs_length(char * A, char * B) {
allocate storage for array L;
for (i = m; i >= 0; i--)
for (j = n; j >= 0; j--) {
if (A[i] == '\0' || B[j] == '\0') L[i,j] = 0;
else if (A[i] == B[j]) L[i,j] = 1 + L[i+1, j+1];
else L[i,j] = max(L[i+1, j], L[i, j+1]);
}
return L[0,0];
}
稍后回溯L阵列以找到特定的子序列,如下所示:
sequence S = empty;
i = 0;
j = 0;
while (i < m && j < n) {
if (A[i]==B[j]) {
add A[i] to end of S;
i++; j++;
}
else if (L[i+1,j] >= L[i,j+1]) i++;
else j++;
}
我还没有把它重写成Javascript,但是现在我知道Rossetta Code的实现工作得很好。所以我的问题:
1。如何修改算法以仅返回序列部分具有给定最小长度的最长公共子序列?
例如,“thisisatest”和“thimplestesting”返回“thistest”,连续部分为“thi”,“s”和“test”。让我们将'limit'定义为连续字符的最低要求,以便将其添加到结果中。限制为3时,结果为“thitest”,限制为4,结果为“test”。对于我的用途,我不仅要获得长度,而且要获得第一个字符串中的实际序列及其索引。如果需要稍后回溯,则无关紧要。
2。这样的修改会降低复杂性还是增加它?
根据我的理解,分析整个后缀树可能是找到符合限制的子序列的解决方案吗?如果正确,是否比原始算法复杂得多?。
第3。您是否可以优化LCS算法,无论是否经过修改,知道相同的源字符串与大量目标字符串进行比较?
目前我只是迭代目标字符串找到LCS并选择具有最长子序列的字符串。是否可以对源字符串进行任何重要的预处理以缩短时间?
欢迎回答我的任何问题,或者只是提示进一步研究的地方。 感谢您的时间! :)