forked from c910335/LCS-Problem-in-Linear-Space
-
Notifications
You must be signed in to change notification settings - Fork 0
/
main.cxx
71 lines (60 loc) · 1.91 KB
/
main.cxx
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
#include <algorithm>
#include <iostream>
#include <iterator>
#include <string>
#include <string_view>
#include <vector>
template<class Iterator>
std::vector<int> scoresBetween(const Iterator &, const Iterator &, const Iterator &, const Iterator &);
std::string lcs(const std::string_view &, const std::string_view &);
int main() {
int T;
std::ios::sync_with_stdio(false);
std::cin >> T;
while (T--) {
std::string X, Y;
std::cin >> X >> Y;
std::cout << lcs(X, Y) << std::endl;
}
return 0;
}
std::string lcs(const std::string_view &x, const std::string_view &y) {
if (x.length() == 0 || y.length() == 0) return "";
if (x.length() == 1 && y.find_first_of(x) != std::string_view::npos) return { x[0] };
if (y.length() == 1 && x.find_first_of(y) != std::string_view::npos) return { y[0] };
auto mid = x.length() / 2;
auto scores = scoresBetween(
x.cbegin(), x.cbegin() + mid,
y.cbegin(), y.cend()
);
auto scoresRight = scoresBetween(
x.crbegin(), x.crbegin() + (x.length() - mid),
y.crbegin(), y.crend()
);
std::transform(scores.cbegin(), scores.cend(), scoresRight.crbegin(), scores.begin(), std::plus<int>());
auto maxIterator = std::max_element(scores.cbegin(), scores.cend());
auto secant = std::distance(scores.cbegin(), maxIterator);
return *maxIterator == 0 ? "" : (
lcs(x.substr(0, mid), y.substr(0, secant)) +
lcs(x.substr(mid), y.substr(secant))
);
}
template<class Iterator>
std::vector<int> scoresBetween(const Iterator &xStart, const Iterator &xEnd, const Iterator &yStart, const Iterator &yEnd) {
std::vector<int> scores(std::distance(yStart, yEnd) + 1, 0);
int preScore = 0;
for (auto x = xStart; x != xEnd; ++x) {
preScore = 0;
for (int i = 0; yStart + i != yEnd; ++i) {
auto y = yStart + i;
auto tmp = scores[i + 1];
scores[i + 1] = std::max({
*x == *y ? preScore + 1 : 0,
scores[i],
scores[i + 1]
});
preScore = tmp;
}
}
return scores;
}