Удалить элементы из вектора c ++, где условие удаления зависит от других элементов - PullRequest
1 голос
/ 23 февраля 2012

Стандартный способ удаления определенных элементов из вектора в C ++ - это идиома удаления / стирания.Однако предикат, переданный remove_if, принимает в качестве аргумента только рассматриваемый элемент вектора.Есть ли хороший способ STL сделать это, если предикат зависит от других элементов массива?

Чтобы привести конкретный пример, рассмотрите возможность удаления всех дубликатов числа, следующих непосредственно за ним.Здесь условие удаления n-го элемента зависит от (n-1) -го элемента.

До: 11234555111333
После: 1234513

Ответы [ 3 ]

2 голосов
/ 23 февраля 2012

Другие упомянутые std::unique уже для вашего конкретного примера.Boost.Range имеет адаптер adjacent_filtered , который передает текущий и следующий элемент в диапазоне вашему предикату и, благодаря предикату, применим для более широкого диапазона проблем.Boost.Range, однако, также имеет адаптер uniqued .

Другая возможность - просто сохранить ссылку на диапазон, что легко сделать с помощью лямбды в C ++ 11:

std::vector<T> v;
v.erase(std::remove_if(v.begin(), v.end(), 
    [&](T const& x){
      // use v, with std::find for example
    }), v.end());
2 голосов
/ 23 февраля 2012

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

Пример для std::string для простоты:

#include <string>
#include <iostream>
#include <algorithm>

int main()
{
    std::string str = "11234555111333";
    str.erase(std::unique(str.begin(), str.end()), str.end());
    std::cout << str;   // 1234513
}
0 голосов
/ 23 февраля 2012

На мой взгляд, будет проще использовать простой алгоритм обхода (через for), чем использовать std :: bind.Конечно, с помощью std :: bind вы можете использовать другие функции и предикаты (которые зависят от предыдущих элементов).Но в вашем примере вы можете сделать это с помощью простого std :: unique.

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