set_intersection на диапазон диапазонов - PullRequest
2 голосов
/ 02 февраля 2020

Почему невозможно сделать следующее:

std::vector<std::vector<int>> v1{{0,0}, {1,0}, {1,1}, {0,1}};
std::vector<std::vector<int>> v2{{1,0}, {2,0}, {2,1}, {1,1}};
auto p = ranges::set_intersection(v1,v2);

Где результат p будет {{1,0}, {1,1}}. Я предполагаю, что я прошу соответствующие подмножества. Было бы замечательно, если бы set_intersection принял пользовательский предикат для обеспечения такого поведения. Я могу придумать хотя бы один способ сделать это, используя другие диапазоны, например:

  auto equal = [](auto&& t){return ranges::equal(std::get<0>(t), std::get<1>(t));};

  auto matching_subsets = ranges::views::cartesian_product(v1,v2)
    | ranges::views::filter(equal)
    | ranges::views::transform([](auto&& t){return std::get<0>(t);});

Я представляю что-то вроде:

auto p = ranges::set_intersection(v1, v2, ranges::equal);

1 Ответ

1 голос
/ 02 февраля 2020

Мы можем использовать std::set_intersection (как упоминалось в комментариях) и делать следующее:

std::vector<std::vector<int>> v1{{0,0}, {1,0}, {1,1}, {0,1}};
std::vector<std::vector<int>> v2{{1,0}, {2,0}, {2,1}, {1,1}};
std::sort(v1.begin(), v1.end());
std::sort(v2.begin(), v2.end());
std::vector<std::vector<int>> v_intersection;

std::set_intersection(v1.begin(), v1.end(),
                      v2.begin(), v2.end(),
                      std::back_inserter(v_intersection));
for(const auto& v : v_intersection){
    for(const auto& n : v){
        cout<<n<<" ";
    }
    cout<<endl;
}

Вывод

1 0 
1 1

Обратите внимание, что два входных диапазона должны быть отсортирован для этого работать.

...