-
Notifications
You must be signed in to change notification settings - Fork 3
/
Copy pathlongest_common_subsequence.cpp
102 lines (93 loc) · 3.65 KB
/
longest_common_subsequence.cpp
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
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
/**
* Compute the longest common subsequence of two or three sequences.
*/
#include "longest_common_subsequence.hpp"
#include <unordered_map>
using namespace std;
int longest_common_subsequence(vector<int> const& x,
vector<int> const& y,
int xi,
int yi,
unordered_map<int, unordered_map<int, int>>& cache) {
if (xi < 0 || yi < 0) {
return 0;
}
if (cache.find(xi) != cache.end() && cache[xi].find(yi) != cache[xi].end()) {
return cache[xi][yi];
}
if (x[xi] == y[yi]) {
cache[xi][yi] = 1 + longest_common_subsequence(x, y, xi - 1, yi - 1, cache);
} else {
cache[xi][yi] = max(longest_common_subsequence(x, y, xi - 1, yi, cache),
longest_common_subsequence(x, y, xi, yi - 1, cache));
}
return cache[xi][yi];
}
int longest_common_subsequence(vector<int> const& x,
vector<int> const& y,
vector<int> const& z,
int xi,
int yi,
int zi,
unordered_map<int, unordered_map<int, unordered_map<int, int>>>& cache) {
if (xi < 0 || yi < 0 || zi < 0) {
return 0;
}
if (cache.find(xi) != cache.end() && cache[xi].find(yi) != cache[xi].end() &&
cache[xi][yi].find(zi) != cache[xi][yi].end()) {
return cache[xi][yi][zi];
}
if (x[xi] == y[yi] && y[yi] == z[zi]) {
cache[xi][yi][zi] = 1 + longest_common_subsequence(x, y, z, xi - 1, yi - 1, zi - 1, cache);
} else {
cache[xi][yi][zi] = max(max(longest_common_subsequence(x, y, z, xi - 1, yi, zi, cache),
longest_common_subsequence(x, y, z, xi, yi - 1, zi, cache)),
longest_common_subsequence(x, y, z, xi, yi, zi - 1, cache));
}
return cache[xi][yi][zi];
}
vector<int> longest_common_subsequence(vector<int> const& x, vector<int> const& y) {
unordered_map<int, unordered_map<int, int>> cache;
int max_length = longest_common_subsequence(x, y, x.size() - 1, y.size() - 1, cache);
vector<int> lcs(max_length);
int xi = x.size() - 1, yi = y.size() - 1;
int lcsi = cache[xi][yi];
while (xi >= 0 && yi >= 0) {
if (x[xi] == y[yi]) {
lcs[lcsi - 1] = x[xi];
xi--;
yi--;
lcsi--;
} else if (cache[xi - 1][yi] > cache[xi][yi - 1]) {
xi--;
} else {
yi--;
}
}
return lcs;
}
vector<int> longest_common_subsequence(std::vector<int> const& x,
std::vector<int> const& y,
std::vector<int> const& z) {
unordered_map<int, unordered_map<int, unordered_map<int, int>>> cache;
int max_length = longest_common_subsequence(x, y, z, x.size() - 1, y.size() - 1, z.size() - 1, cache);
vector<int> lcs(max_length);
int xi = x.size() - 1, yi = y.size() - 1, zi = z.size() - 1;
int lcsi = cache[xi][yi][zi];
while (xi >= 0 && yi >= 0 && zi >= 0) {
if (x[xi] == y[yi] && y[yi] == z[zi]) {
lcs[lcsi - 1] = x[xi];
xi--;
yi--;
zi--;
lcsi--;
} else if (cache[xi - 1][yi][zi] >= cache[xi][yi - 1][zi] && cache[xi - 1][yi][zi] >= cache[xi][yi][zi - 1]) {
xi--;
} else if (cache[xi][yi - 1][zi] >= cache[xi - 1][yi][zi] && cache[xi][yi - 1][zi] >= cache[xi][yi][zi - 1]) {
yi--;
} else {
zi--;
}
}
return lcs;
}