Удалить дубликаты в двух векторах на основе дубликатов на первом векторе - PullRequest
0 голосов
/ 21 апреля 2020

У меня есть два вектора, которые связаны между собой. Вектор имеет одинаковый размер, и его содержимое соответствует 1: 1 в том смысле, что он может быть рефакторингом в один вектор некоторой структуры. Я пытаюсь удалить дубликаты на первом векторе, и это должно совпадать во втором векторе.

v1 = [5 4 3 7 6 5 2 3]
v2 = [0 1 2 3 4 5 6 7]

Так как 5 и 3 повторяются в v1, результат должен быть

v1 = [5 4 3 7 6 2]
v2 = [0 1 2 3 4 6]

Порядок может быть изменен, если отношение одинаково.

Я пытаюсь добиться этого с помощью библиотеки range-v3.

std::vector<unsigned int>  v1;
std::vector<double> v2;

auto v1Andv2 = range::views::zip(v1, v2);
ranges::sort(v1Andv2)
// ranges::unique(v1Andv2) // Doesnt compile
auto lastIt = std::unique(std::begin(v1Andv2), std::end(v1Andv2), [](const auto &a, const auto &b) {
    // Since the second value of the zip is a double and could be slightly different, 
    // I am only interested in first one
    return std::get<0>(a) == std::get<0>(b);
});

v1.erase(???, std::end(v1));
v2.erase(???, std::end(v2));

Понятия не имею, что мне положить в ??? чтобы получить итератор каждое значение в zip. Кроме того, почему диапазоны :: действия :: уникальные не работают в этом случае?

1 Ответ

0 голосов
/ 21 апреля 2020

Проблема в том, что вы не можете sort или иным образом изменить view. Если вы просто создаете вектор пар, то вы можете без проблем использовать sort и unique:

auto vv = ranges::views::zip(v1, v2) | 
          ranges::to<std::vector<std::pair<int,int>>>;

vv |= ranges::actions::sort([](auto const &a, auto const &b)
                            { return a.first < b.first; })
    | ranges::actions::unique([](auto const &a, auto const &b)
                              { return a.first == b.first; });

Вот рабочая демоверсия .

Вы даже можете переставить его обратно в исходный порядок, снова набрав sort, например:

vv |= ranges::actions::sort([](auto const &a, auto const &b)
                            { return a.first < b.first; })
   | ranges::actions::unique([](auto const &a, auto const &b)
                             { return a.first == b.first; })
   | ranges::actions::sort([](auto const &a, auto const &b)
                           { return a.second < b.second; });

Вот демо .

...