namespace v1
{
template <typename CHAR>
std::basic_string<CHAR> lcs(const CHAR * s1, const CHAR * s2)
{
typedef std::basic_string<CHAR> String;
String ret;
int m = s1 != NULL ? static_cast<int>(strlen(s1)) : 0;
int n = s2 != NULL ? static_cast<int>(strlen(s2)) : 0;
if (m > 0 && n > 0) {
std::vector<std::vector<String>> cache(m + 1, std::vector<String>(n + 1));
for (int i = m - 1; i >= 0; --i) {
for (int j = n - 1; j >= 0; --j) {
String r1 = cache[i + 1][j];
String r2 = cache[i][j + 1];
String r3;
String * pr = r1.length() >= r2.length() ? &r1 : &r2;
if (s1[i] == s2[j]) {
r3.push_back(s1[i]);
r3 += cache[i + 1][j + 1];
if (pr->length() < r3.length()) {
pr = &r3;
}
}
cache[i][j] = std::move(*pr);
}
}
ret.swap(cache[0][0]);
}
return std::move(ret);
}
}
namespace v2
{
namespace details
{
struct record
{
int length;
short row_increment;
short column_increment;
};
template <typename CHAR>
std::basic_string<CHAR> get_string(const CHAR * s1, const CHAR * s2, std::vector<std::vector<record>> const & cache)
{
std::basic_string<CHAR> ret;
for (int i = 0, j = 0; ; ) {
const record & r = cache[i][j];
if (r.row_increment != 0 || r.column_increment != 0) {
if (r.row_increment == 1 && r.column_increment == 1) {
ret.push_back(s1[i]);
}
i += r.row_increment;
j += r.column_increment;
}
else {
break;
}
}
return std::move(ret);
}
}
template <typename CHAR>
std::basic_string<CHAR> lcs(const CHAR * s1, const CHAR * s2)
{
typedef std::basic_string<CHAR> String;
String ret;
int m = s1 != NULL ? static_cast<int>(strlen(s1)) : 0;
int n = s2 != NULL ? static_cast<int>(strlen(s2)) : 0;
if (m > 0 && n > 0) {
std::vector<std::vector<details::record>> cache(m + 1, std::vector<details::record>(n + 1, details::record{0, 0, 0}));
for (int i = m - 1; i >= 0; --i) {
for (int j = n - 1; j >= 0; --j) {
details::record r1 = { cache[i + 1][j].length, 1, 0 };
details::record r2 = { cache[i][j + 1].length, 0, 1 };
details::record r3 = { cache[i + 1][j + 1].length + 1, 1, 1 };
details::record * pr = r1.length >= r2.length ? &r1 : &r2;
if (s1[i] == s2[j]) {
if (pr->length < r3.length) {
pr = &r3;
}
}
cache[i][j] = *pr;
}
}
ret.swap(details::get_string(s1, s2, cache));
}
return std::move(ret);
}
}