11template <
typename InputIt1,
typename InputIt2>
12DecomposedSet<InputIt1, InputIt2, InputIt1> set_decomposition(SplittedSentenceView<InputIt1> a,
13 SplittedSentenceView<InputIt2> b)
18 RangeVec<InputIt1> intersection;
19 RangeVec<InputIt1> difference_ab;
20 RangeVec<InputIt2> difference_ba = b.words();
22 for (
const auto& current_a : a.words()) {
23 auto element_b = std::find(difference_ba.begin(), difference_ba.end(), current_a);
25 if (element_b != difference_ba.end()) {
26 difference_ba.erase(element_b);
27 intersection.push_back(current_a);
30 difference_ab.push_back(current_a);
34 return {difference_ab, difference_ba, intersection};
37template <
class InputIt1,
class InputIt2>
38std::pair<InputIt1, InputIt2> rf_mismatch(InputIt1 first1, InputIt1 last1, InputIt2 first2, InputIt2 last2)
40 while (first1 != last1 && first2 != last2 && *first1 == *first2)
43 return std::make_pair(first1, first2);
49template <
typename InputIt1,
typename InputIt2>
50size_t remove_common_prefix(Range<InputIt1>& s1, Range<InputIt2>& s2)
52 auto first1 = std::begin(s1);
53 size_t prefix =
static_cast<size_t>(
54 std::distance(first1, rf_mismatch(first1, std::end(s1), std::begin(s2), std::end(s2)).first));
55 s1.remove_prefix(prefix);
56 s2.remove_prefix(prefix);
63template <
typename InputIt1,
typename InputIt2>
64size_t remove_common_suffix(Range<InputIt1>& s1, Range<InputIt2>& s2)
66 auto rfirst1 = s1.rbegin();
67 size_t suffix =
static_cast<size_t>(
68 std::distance(rfirst1, rf_mismatch(rfirst1, s1.rend(), s2.rbegin(), s2.rend()).first));
69 s1.remove_suffix(suffix);
70 s2.remove_suffix(suffix);
77template <
typename InputIt1,
typename InputIt2>
78StringAffix remove_common_affix(Range<InputIt1>& s1, Range<InputIt2>& s2)
80 return StringAffix{remove_common_prefix(s1, s2), remove_common_suffix(s1, s2)};
83template <
typename,
typename =
void>
84struct is_space_dispatch_tag : std::integral_constant<int, 0> {};
86template <
typename CharT>
87struct is_space_dispatch_tag<CharT, typename std::enable_if<sizeof(CharT) == 1>::type>
88 : std::integral_constant<int, 1> {};
93template <
typename CharT>
94bool is_space_impl(
const CharT ch, std::integral_constant<int, 0>)
125 case 0x3000:
return true;
133template <
typename CharT>
134bool is_space_impl(
const CharT ch, std::integral_constant<int, 1>)
146 case 0x0020:
return true;
155template <
typename CharT>
156bool is_space(
const CharT ch)
158 return is_space_impl(ch, is_space_dispatch_tag<CharT>{});
161template <
typename InputIt,
typename CharT>
162SplittedSentenceView<InputIt> sorted_split(InputIt first, InputIt last)
164 RangeVec<InputIt> splitted;
167 for (; first != last; first = second + 1) {
168 second = std::find_if(first, last, is_space<CharT>);
170 if (first != second) {
171 splitted.emplace_back(first, second);
174 if (second == last)
break;
177 std::sort(splitted.begin(), splitted.end());
179 return SplittedSentenceView<InputIt>(splitted);