更新:
重新阅读问题后,我意识到您可能想同时执行所有三个操作。
我们可以通过将三个函数合二为一并返回一个元组,将外循环的迭代次数减少到一次,并删除一个内循环:
#include <iostream>
#include <vector>
#include <algorithm>
#include <iterator>
#include <tuple>
std::tuple<std::vector<unsigned>, std::vector<unsigned>, std::vector<unsigned>>
find_everything(const std::vector<unsigned>& a,
const std::vector<std::pair<unsigned,unsigned> >& b1,
const std::vector<std::pair<unsigned,unsigned> >& b2)
{
std::vector<unsigned> r1, r2, both;
for (auto x : a)
{
auto either = false;
auto i = std::find_if(std::begin(b1),
std::end(b1),
[x](const auto& range)
{ return x >= range.first && x < range.second; });
if (i != std::end(b1)) {
either = true;
r1.push_back(x);
}
i = std::find_if(std::begin(b2),
std::end(b2),
[x](const auto& range)
{ return x >= range.first && x < range.second; });
if (i != std::end(b2)) {
either = true;
r2.push_back(x);
}
if (either) {
both.push_back(x);
}
}
return std::make_tuple(std::move(r1), std::move(r2), std::move(both));
}
int main()
{
using namespace std;
vector<unsigned> A { 2,4,6,8,9,10,34,74,79,81,89,91,95 };
vector<pair<unsigned,unsigned> > B1={ {4, 5}, {8, 10}, {90, 99} };
vector<pair<unsigned,unsigned> > B2={ {2, 3}, {29, 40}, {60, 85} };
auto results = find_everything(A, B1, B2);
const auto& r1 = std::get<0>(results);
const auto& r2 = std::get<1>(results);
const auto& both = std::get<2>(results);
copy(begin(r1), end(r1), ostream_iterator<unsigned>(cout, ", "));
cout << endl;
copy(begin(r2), end(r2), ostream_iterator<unsigned>(cout, ", "));
cout << endl;
copy(begin(both), end(both), ostream_iterator<unsigned>(cout, ", "));
cout << endl;
return 0;
}
预期结果:
4, 8, 9, 91, 95,
2, 34, 74, 79, 81,
2, 4, 8, 9, 34, 74, 79, 81, 91, 95,
进一步的工作:
如果数据集很大,我们可以立即做出两个明显的改进:
-
由于 A、B1 和 B2 已排序,我们可以跟踪“当前”匹配迭代器,减少每次匹配或不匹配的搜索空间(这开始争论 std::lower_bound)
或者如果 A 明显大于 B1 和 B2,我们可以并行搜索。
玩得开心:)