|
|
-
- 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);
- }
|