Удалить общие объекты из двух векторов?

Мне удалось выяснить самостоятельно ... если кому-то это понадобится:

5
задан yesraaj 13 March 2009 в 07:06
поделиться

6 ответов

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

Вот пример использования:

#include <algorithm>
#include <vector>

int main(int argc, char **argv) {

    std::vector<int> v1;
    v1.push_back(1);
    v1.push_back(2);
    v1.push_back(3);
    v1.push_back(4);
    v1.push_back(5);
    v1.push_back(6);

    std::vector<int> v2;
    v2.push_back(2);
    v2.push_back(4);
    v2.push_back(6);
    v2.push_back(8);

    // Ranges must be sorted!
    std::sort(v1.begin(), v1.end());
    std::sort(v2.begin(), v2.end());

    std::vector<int> res; // Will contain the symmetric difference
    std::set_symmetric_difference(v1.begin(), v1.end(), 
                                  v2.begin(), v2.end(), 
                                  std::back_inserter(res));

    // Copy result to the output
    std::copy(res.begin(), res.end(), std::ostream_iterator<int>(cout, " "));
    // Prints "1 3 5"

    return 0;
}

std::set_symmetric_difference берет два, располагаются (т.е. две пары OutputIterators) и InputIterator, куда он поместит результат. Это также возвращает итератор в конец диапазона результата.


Править

Я просто прочитал Ваши комментарии к Вашему вопросу. Если Вы хотите, чтобы эти два исходных вектора были изменены, можно использовать std::set_difference:

vector<int>::iterator endRange;
endRange = set_difference(v1.begin(), v1.end(), 
                          v2.begin(), v2.end(), 
                          v1.begin());
v1.erase(endRange, v1.end());

Здесь, мы помещаем результат разности множеств v1 - v2 в v1. Однако мы не можем сделать наоборот, так как v1 теперь изменяется. Решение состоит в том, чтобы вычислить пересечение v1 и v2 и затем различия с этим пересечением std::set_intersection :

vector<int> inter;
set_intersection(v1.begin(), v1.end(),
                 v2.begin(), v2.end(),
                 back_inserter(inter));
// inter is "2 4 6"

v1.erase(set_difference(v1.begin(), v1.end(),
                        inter.begin(), inter.end(),
                        v1.begin()),
         v1.end());
// v1 is "1 3 5"

v2.erase(set_difference(v2.begin(), v2.end(),
                        inter.begin(), inter.end(),
                        v2.begin()),
         v2.end());
// v2 is "8"

Я предполагаю, что существует намного больше производительных решений, но этот ясен, и действительно передайте свои намерения при помощи широко известных stl алгоритмов.

8
ответ дан 14 December 2019 в 01:18
поделиться

В stl заголовке алгоритм является функцией, вызванной "set_symmetric_difference", который поместит все элементы одного, но не оба исходных диапазона в единственный целевой диапазон.

Примите во внимание, что оба из диапазонов должны запуститься отсортированный.

документация MSDN

1
ответ дан 14 December 2019 в 01:18
поделиться

Отсортируйте эти 2 вектора, затем идите через них в параллели, делающей общую операцию слияния. Это скажет Вам, какие объекты идентичны.

0
ответ дан 14 December 2019 в 01:18
поделиться

Наивный путь состоит в том, чтобы сделать n^2 повторение, сравнивающее каждый элемент в первом векторе против каждого элемента во втором массиве и добавляющее любые соответствия к третьему вектору. При окончании n^2 повторения Вы обходите третий вектор и удаляете те объекты из первых двух.

Не лучшее решение, но в зависимости от того, как большой Вы ожидаете, векторы, чтобы быть этим могут быть среди самого простого.

0
ответ дан 14 December 2019 в 01:18
поделиться

Для каждой пары объектов в class1a и class1b, добавьте их к выходному набору, если они не равны. Еще, добавьте только один такой экземпляр. Повторитесь для минимума длины массивов. Если Вы будете длиннее, то с Вами еще оставят, некоторые - пытаются добавить все они к набору.

0
ответ дан 14 December 2019 в 01:18
поделиться

Начните добавлять значение вектора в Наборе. Переопределите, равняется методу class1 и class2, чтобы решить, как Вы хотите объект быть равными. Если Вы не переопределяете, равняется по умолчанию ==, будет использоваться для сравнения и так как объекты имеют другой класс ==, будет всегда возвращать false. Таким образом, необходимо переопределить, равняется методу.

0
ответ дан 14 December 2019 в 01:18
поделиться
Другие вопросы по тегам:

Похожие вопросы: