19 #ifndef VECTOR_SET_HPP
20 #define VECTOR_SET_HPP
31 template <
typename T,
typename U>
32 Vector<T> intersect(
const Vector<T>& v1,
const Vector<U>& v2);
34 template <
typename T,
typename U,
typename I>
35 std::pair<Vector<I>, Vector<I>> intersect_idx(
const Vector<T>& v1,
const Vector<U>& v2);
37 template <
typename T,
typename U>
38 Vector<T> _union(
const Vector<T>& v1,
const Vector<U>& v2);
40 template <
typename T,
typename U,
typename I>
41 std::pair<Vector<I>, Vector<I>> union_idx(
const Vector<T>& v1,
const Vector<U>& v2);
44 template <
typename T,
typename U>
45 Vector<T> setdiff(
const Vector<T>& v1,
const Vector<U>& v2);
48 template <
typename T,
typename U,
typename I>
49 std::pair<Vector<I>, Vector<I>> setdiff_idx(
const Vector<T>& v1,
const Vector<U>& v2);
59 template <
typename T,
typename U,
template <
typename,
typename>
class F>
60 static Vector<T> conditional_sort_helper(
const Vector<T>& v1,
const Vector<U>& v2)
62 if (!v1.isOrdered() && !v2.isOrdered()) {
64 std::sort(s1.begin(), s1.end());
66 std::sort(s2.begin(), s2.end());
67 return F<T,U>::f(s1, s2);
69 if (!v1.isOrdered()) {
71 std::sort(s1.begin(), s1.end());
72 return F<T,U>::f(s1, v2);
74 if (!v2.isOrdered()) {
76 std::sort(s2.begin(), s2.end());
77 return F<T,U>::f(v1, s2);
79 return F<T,U>::f(v1, v2);
83 template <
typename T,
typename U,
typename I,
template <
typename,
typename,
typename>
class F>
84 static std::pair<Vector<I>, Vector<I>>
85 conditional_sort_idx_helper(
const Vector<T>& v1,
const Vector<U>& v2)
88 if (!v1.isOrdered() && !v2.isOrdered()) {
90 std::sort(s1.begin(), s1.end());
92 std::sort(s2.begin(), s2.end());
93 return F<T,U,I>::f(s1, s2);
95 if (!v1.isOrdered()) {
97 std::sort(s1.begin(), s1.end());
98 return F<T,U,I>::f(s1, v2);
100 if (!v2.isOrdered()) {
102 std::sort(s2.begin(), s2.end());
103 return F<T,U,I>::f(v1, s2);
105 return F<T,U,I>::f(v1, v2);
109 template <
typename T,
113 template <
typename,
typename,
typename,
typename>
class F>
114 static std::pair<Vector<I>, Vector<I>>
115 conditional_sort_idx_nan_helper(
const Vector<T>& v1,
const Vector<U>& v2)
118 if (!v1.isOrdered() && !v2.isOrdered()) {
120 std::sort(s1.begin(), s1.end());
122 std::sort(s2.begin(), s2.end());
123 return F<T,U,I,NANF>::f(s1, s2);
125 if (!v1.isOrdered()) {
127 std::sort(s1.begin(), s1.end());
128 return F<T,U,I,NANF>::f(s1, v2);
130 if (!v2.isOrdered()) {
132 std::sort(s2.begin(), s2.end());
133 return F<T,U,I,NANF>::f(v1, s2);
135 return F<T,U,I,NANF>::f(v1, v2);
143 template <
typename T,
typename U>
148 size_t i1 = 0, i2 = 0;
149 while (i1 < v1.size() && i2 < v2.size()) {
150 if (v1[i1] < v2[i2]) {
152 }
else if (v1[i1] > v2[i2]) {
155 if (res.size()==0 || v1[i1] != res.back()) {
156 res.push_back(v1[i1]);
168 template <
typename T,
typename U>
171 return conditional_sort_helper<T, U, intersect_helper>(v1, v2);
175 template <
typename T,
typename U,
typename I>
180 size_t i1 = 0, i2 = 0;
181 while (i1 < v1.size() && i2 < v2.size()) {
182 if (v1[i1] < v2[i2]) {
184 }
else if (v1[i1] > v2[i2]) {
187 if (v1.size()==0 || v1[i1] != v1[i1-1]) {
188 res.first.push_back(i1+1);
189 res.second.push_back(i2+1);
200 template <
typename T,
typename U,
typename I>
203 return conditional_sort_idx_helper<T, U, I, intersect_idx_helper>(v1, v2);
210 template <
typename T,
typename U>
215 size_t i1 = 0, i2 = 0;
216 while (i1 < v1.size() && i2 < v2.size()) {
217 if (v1[i1] < v2[i2]) {
218 if (res.size()==0 || v1[i1] != res.back()) {
219 res.push_back(v1[i1]);
222 }
else if (v1[i1] > v2[i2]) {
223 if (res.size()==0 || v2[i2] != res.back()) {
224 res.push_back(v2[i2]);
228 if (res.size()==0 || v1[i1] != res.back()) {
229 res.push_back(v1[i1]);
236 while (i1 < v1.size()) {
237 if (i1==0 || v1[i1] != v1[i1-1]) {
238 res.push_back(v1[i1]);
242 while (i2 < v2.size()) {
243 if (i2==0 || v2[i2] != v2[i2-1]) {
244 res.push_back(v2[i2]);
253 template <
typename T,
typename U>
256 return conditional_sort_helper<T, U, union_helper>(v1, v2);
260 template <
typename T,
typename U,
typename I,
typename NANF>
265 size_t i1 = 0, i2 = 0;
266 while (i1 < v1.size() && i2 < v2.size()) {
267 if (v1[i1] < v2[i2]) {
268 if (i1==0 || v1[i1] != v1[i1-1]) {
269 res.first.push_back(i1+1);
270 res.second.push_back(NANF::f());
273 }
else if (v1[i1] > v2[i2]) {
274 if (i2==0 || v2[i2] != v1[i2-1]) {
275 res.first.push_back(NANF::f());
276 res.second.push_back(i2+1);
280 if (i1==0 || v1[i1] != v1[i1-1]) {
281 res.first.push_back(i1+1);
282 res.second.push_back(i2+1);
289 while (i1 < v1.size()) {
290 if (i1==0 || v1[i1] != v1[i1-1]) {
291 res.first.push_back(i1+1);
292 res.second.push_back(NANF::f());
296 while (i2 < v2.size()) {
297 if (i2==0 || v2[i2] != v2[i2-1]) {
298 res.first.push_back(NANF::f());
299 res.second.push_back(i2+1);
308 template <
typename T,
typename U,
typename I,
template <
typename>
class NANF>
312 return conditional_sort_idx_nan_helper<T, U, I, NANF<I>,
union_idx_helper>(v1, v2);
319 template <
typename T,
typename U>
325 size_t i1 = 0, i2 = 0;
326 while (i1 < v1.size() && i2 < v2.size()) {
327 if (v1[i1] < v2[i2]) {
328 res.push_back(v1[i1++]);
329 }
else if (v1[i1] > v2[i2]) {
339 while (i1 < v1.size()) {
340 res.push_back(v1[i1++]);
347 template <
typename T,
typename U>
350 return conditional_sort_helper<T, U, setdiff_helper>(v1, v2);
354 template <
typename T,
typename U,
typename I>
359 size_t i1 = 0, i2 = 0;
360 while (i1 < v1.size() && i2 < v2.size()) {
361 if (v1[i1] < v2[i2]) {
362 res.first.push_back(i1+1);
364 }
else if (v1[i1] > v2[i2]) {
365 res.second.push_back(i2+1);
374 while (i1 < v1.size()) {
375 res.first.push_back(i1+1);
379 while (i2 < v2.size()) {
380 res.second.push_back(i2+1);
388 template <
typename T,
typename U,
typename I>
391 return conditional_sort_idx_helper<T, U, I, setdiff_idx_helper>(v1, v2);