3#ifndef STEP20_LONGEST_COMMON_SUBSTRING_HPP
4#define STEP20_LONGEST_COMMON_SUBSTRING_HPP
13 std::unsigned_integral Size,
15 std::weakly_incrementable O>
16O copy(std::basic_string<Char>&& str, Size mid,
const Compare& comp, O result)
19 auto first = arr.
data();
20 auto last = first + arr.size();
21 auto substr = std::basic_string_view{last, last};
22 auto lcp = arr.lcp_array();
23 for (Size i = 1; i < arr.size(); ++i) {
24 auto prev = arr[i - 1];
26 if ((prev < mid) == (cur < mid))
28 auto pos = std::min<Size>(prev, cur);
29 auto len = std::min<Size>(lcp[i - 1], mid - pos);
30 if (len > substr.size())
31 substr = std::basic_string_view{first + pos, first + pos + len};
33 return std::ranges::copy(substr, result).out;
44template <std::ranges::input_range R1,
45 std::ranges::input_range R2,
46 std::weakly_incrementable O,
47 class Compare = std::less<>>
48O
copy(
const R1& r1,
const R2& r2, O result,
const Compare& comp = {})
50 using char_t = std::common_type_t<std::ranges::range_value_t<R1>,
51 std::ranges::range_value_t<R2>>;
52 auto str = std::basic_string<char_t>{};
53 str.append(std::ranges::begin(r1), std::ranges::end(r1));
54 auto mid = str.size();
55 str.append(std::ranges::begin(r2), std::ranges::end(r2));
56 if (str.size() < std::numeric_limits<uint8_t>::max())
57 return detail::copy(std::move(str), (uint8_t)mid, comp, result);
58 if (str.size() < std::numeric_limits<uint16_t>::max())
59 return detail::copy(std::move(str), (uint16_t)mid, comp, result);
60 if (str.size() < std::numeric_limits<uint32_t>::max())
61 return detail::copy(std::move(str), (uint32_t)mid, comp, result);
62 return detail::copy(std::move(str), mid, comp, result);
Kasai's algorithm for constructing longest common prefix array.
Definition suffix_array.hpp:122
const Char * data() const
Definition suffix_array.hpp:27
Definition longest_common_substring.hpp:9
O copy(const R1 &r1, const R2 &r2, O result, const Compare &comp={})
Find the longest substring of two strings.
Definition longest_common_substring.hpp:48