step20
Loading...
Searching...
No Matches
longest_common_subsequence.hpp
Go to the documentation of this file.
1// Andrew Naplavkov
2
3#ifndef STEP20_LONGEST_COMMON_SUBSEQUENCE_HPP
4#define STEP20_LONGEST_COMMON_SUBSEQUENCE_HPP
5
6#include "detail/hirschberg.hpp"
7#include "detail/utility.hpp"
8#include <cstdint>
9
11namespace detail {
12
13template <class Equal>
14struct table {
15 const Equal& eq;
16
17 template <std::random_access_iterator I1, std::random_access_iterator I2>
18 auto last_row(I1 first1, I1 last1, I2 first2, I2 last2) const
19 {
20 auto size1 = last1 - first1;
21 auto size2 = last2 - first2;
22 auto tbl = ring_table<uintmax_t, 2>(size2 + 1);
23 for (decltype(size1) l = 1; l <= size1; ++l)
24 for (decltype(size2) r = 1; r <= size2; ++r)
25 tbl[l][r] = eq(first1[l - 1], first2[r - 1])
26 ? tbl[l - 1][r - 1] + 1
27 : std::max(tbl[l - 1][r], tbl[l][r - 1]);
28 return std::move(tbl[size1]);
29 }
30
31 template <bool transposed,
32 std::random_access_iterator I1,
33 std::random_access_iterator I2,
34 std::weakly_incrementable O>
35 O trace_col(I1 first1, I1 last1, I2 first2, I2 last2, O result) const
36 {
37 if constexpr (transposed)
38 return trace_col<!transposed>(first2, last2, first1, last1, result);
39 else {
40 auto it = std::find_first_of(first1, last1, first2, last2, eq);
41 if (it != last1)
42 *result++ = *it;
43 return result;
44 }
45 }
46};
47
48} // namespace detail
49
51
55template <std::ranges::random_access_range R1,
56 std::ranges::random_access_range R2,
57 std::weakly_incrementable O,
58 class Equal = std::equal_to<>>
59O copy(const R1& r1, const R2& r2, O result, const Equal& eq = {})
60{
61 return hirschberg::trace(detail::table<Equal>{eq},
62 std::ranges::begin(r1),
63 std::ranges::end(r1),
64 std::ranges::begin(r2),
65 std::ranges::end(r2),
66 result);
67}
68
69} // namespace step20::longest_common_subsequence
70
71#endif // STEP20_LONGEST_COMMON_SUBSEQUENCE_HPP
Definition longest_common_subsequence.hpp:10
O copy(const R1 &r1, const R2 &r2, O result, const Equal &eq={})
Find the longest subsequence present in two sequences.
Definition longest_common_subsequence.hpp:59