问题和LCS相似,但是要求最长的字串必须连续。
同样可以采取动态规划方法,分别使用两个数组来保存中间计算结果:
1)一个保存当到达位置i,j时,最大的字串长度;
2)另一保存以i,j为截止的位置的连续字串的长度;
每次如果a[i] == b[j]时,比较max_length[i-1][j-1]和length_endinghere[i][j]来进行决策,具体见程序
如果a[i] != b[j]时,类似于LCS问题。
值得注意的一点是,需要一个max来保存取得最大长度时,i,j的位置,开始没有通过max来筛选,出现了错误。
具体代码如下:
#include <stdio.h>
#include <string>
std::string LongestCommonAdjSubsequence(const std::string& string_a, const std::string& string_b) {
size_t a_size = string_a.size();
size_t b_size = string_b.size();
int** length_endinghere = new int*[a_size + 1];
int** max_length = new int*[a_size + 1];
for (int i = 0; i <= a_size; ++i) {
length_endinghere[i] = new int[b_size + 1];
max_length[i] = new int[b_size + 1];
for (int j = 0; j <= b_size; ++j) {
length_endinghere[i][j] = 0;
max_length[i][j] = 0;
}
}
int max_length_found = -1;
int max_end_i = -1;
int max_end_j = -1;
for (int i = 1; i <= a_size; ++i) {
for (int j = 1; j <= b_size; ++j) {
if (string_a[i-1] == string_b[j-1]) {
length_endinghere[i][j] = length_endinghere[i-1][j-1] + 1;
if (max_length[i-1][j-1] < length_endinghere[i][j]) {
max_length[i][j] = length_endinghere[i][j];
if (max_length[i][j] > max_length_found) {
max_end_i = i - max_length_found -1;
max_end_j = j - max_length_found -1;
max_length_found = max_length[i][j];
}
} else {
max_length[i][j] = max_length[i-1][j-1];
}
} else {
if (max_length[i-1][j] > max_length[i][j-1]) {
max_length[i][j] = max_length[i-1][j];
} else {
max_length[i][j] = max_length[i][j-1];
}
length_endinghere[i][j] = 0;
}
}
}
for(int i = 0; i <= a_size; ++i) {
for(int j = 0; j <= b_size; ++j) {
printf("%d ", length_endinghere[i][j]);
}
printf("\n");
}
printf("\n");
for(int i = 0; i <= a_size; ++i) {
for(int j = 0; j <= b_size; ++j) {
printf("%d ", max_length[i][j]);
}
printf("\n");
}
printf("%d %d\n", max_end_i, max_end_j);
for (int i = 0; i <= a_size; ++i) {
delete[] length_endinghere[i];
delete[] max_length[i];
}
delete[] length_endinghere;
delete[] max_length;
std::string ret = "";
if (max_end_i != -1) {
do {
ret += string_a[max_end_i];
} while(string_a[++max_end_i] == string_b[++max_end_j]);
}
return ret;
}
int main(int argc, char** argv) {
std::string string_a = "i love bbbarchery";
std::string string_b = "i also love bbbarchery";
printf("%s\n", LongestCommonAdjSubsequence(string_a, string_b).c_str());
}