|
|
@ -0,0 +1,55 @@ |
|
|
|
|
|
|
|
auto subsequence_boundary(auto start, auto end,auto pred) { |
|
|
|
using live_iterator = decltype(start); |
|
|
|
using distance_t = std::invoke_result_t<decltype(std::distance<live_iterator>), live_iterator, decltype(end)>; |
|
|
|
distance_t distance = std::distance(start, end); |
|
|
|
|
|
|
|
if(distance < 1) { |
|
|
|
return start; |
|
|
|
} |
|
|
|
|
|
|
|
if(distance == 1) { |
|
|
|
return ++start; |
|
|
|
} |
|
|
|
|
|
|
|
live_iterator next = start; |
|
|
|
++next; |
|
|
|
|
|
|
|
while(not pred(*start, *next)) { |
|
|
|
++start; |
|
|
|
++next; |
|
|
|
if(next == end) return next; |
|
|
|
} |
|
|
|
|
|
|
|
return next; |
|
|
|
} |
|
|
|
|
|
|
|
auto longest_matching_subsequence(auto start, auto end, auto pred) { |
|
|
|
using live_iterator = decltype(start); |
|
|
|
using distance_t = std::invoke_result_t<decltype(std::distance<live_iterator>), live_iterator, decltype(end)>; |
|
|
|
live_iterator current = start; |
|
|
|
struct { |
|
|
|
live_iterator best_s; |
|
|
|
live_iterator best_e; |
|
|
|
} results; |
|
|
|
results.best_s = start; |
|
|
|
results.best_e = start; |
|
|
|
distance_t best_length = 0; |
|
|
|
while(current != end) { |
|
|
|
live_iterator next = subsequence_boundary(current, end, pred); |
|
|
|
distance_t subsequence_length = std::distance(current, next); |
|
|
|
if(subsequence_length > best_length) { |
|
|
|
results.best_s = current; |
|
|
|
results.best_e = next; |
|
|
|
best_length = subsequence_length; |
|
|
|
} |
|
|
|
current = next; |
|
|
|
} |
|
|
|
return results; |
|
|
|
} |
|
|
|
|
|
|
|
TEST_CASE("Subsequence") { |
|
|
|
std::vector<int> list = {0,1,2,3,4,5,0,1,0,2,5,8,7}; |
|
|
|
auto [s,e] = longest_matching_subsequence(list.begin(), list.end(), std::greater<int>{}); |
|
|
|
REQUIRE(std::distance(s,e) == 6); |
|
|
|
} |