Разбиение вектора объектов на 2 или более подгрупп - PullRequest
1 голос
/ 28 мая 2011

Я хотел бы разделить вектор ссылок на MyObject (то есть vector<MyObject*>) на 2 или более субвектора на основе некоторых общих черт.

У меня есть функция эквивалентности bool belongToSameGroup(MyObject *x, MyObject *y);, которая равна true, если определенные поля данных MyObject равны, и false в противном случае.Поскольку эта эквивалентность не является общей и предназначена только для конкретной цели, я бы предпочел не перегружать operator==.

Как лучше всего создать, скажем, вектор из <vector<MyObject*> 's (то есть vector< vector<MyObject*> >) такой, что элементы сгруппированы на основе их эквивалентности по функции belongToSameGroup?Я бы предпочел не делать кучу циклов for и максимально использовать алгоритмы и контейнеры STL.

Ответы [ 3 ]

5 голосов
/ 28 мая 2011

Я думаю std::partition это то, что вы хотите. (Эй, это даже в названии вашего вопроса!)

3 голосов
/ 28 мая 2011

Вы можете использовать std::remove_copy_if вместе с итератором обратной вставки для std::vector<MyObject*>. Так это будет выглядеть (где TESTFUNCTION - ваша функция, которая принимает тип MyObject* и возвращает bool):

std::vector<MyObject*> original;

std::vector<MyObject*> partion_A;
std::back_insert_iterator<std::vector<MyObject*> > inserter_A(partion_A);

std::remove_copy_if(original.begin(), original.end(), inserter_A, TESTFUNCTION);

Теперь partition_A будет содержать все значения, для которых TESTFUNCTION имеет значение true. Если вам нужен второй вектор разбиения partion_B, просто создайте еще один TESTFUNCTION_B, который проверяет противоположное условие, а также другой задний вставщик inserter_B, инициализированный значением partion_B.

Два преимущества этого метода по сравнению с std::partition заключаются в том, что 1) он не изменяет исходный вектор, поэтому вероятнее всего будет больше сценариев его использования (т. Е. Ситуации с постоянными итераторами), и 2) его можно запустить на контейнерах, в которых нет двунаправленных итераторов, таких как std::list и т. д.

0 голосов
/ 28 мая 2011

Вам не нужна группа for циклов, вам просто нужно запустить std::for_each для вашего вектора и решить, что делать с каждым элементом. Или используйте std::partition, если вы можете оставить их в одном контейнере, просто реорганизовать.


Как уже упоминалось в комментариях - в стандарте C ++ 11 for поддерживает функциональность, для которой ранее требовался std::for_each.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...