Мы можем использовать remove_if в C ++ для удаления элементов из вектора за линейное время на основе предиката, который работает с элементами.
bool condition(double d) {...}
vector<double> data = ...
std::remove_if (data.begin(), data.end(), condition);
Что если мое состояние зависит не от значений, а от показателей? Другими словами, если я хотел удалить все нечетно-проиндексированные элементы, или какой-то произвольный набор индексов и т. Д.?
bool condition(int index) {//returns whether this index should be removed}
vector<double> data = ...
std::remove_if (data.begin(), data.end(), ???);
Вы можете использовать арифметику указателей, чтобы найти индекс определенного элемента, который std::remove_if
переходит к предикату:
std::remove_if(data.begin(), data.end(),
[](const double& d) { return (&d - &*data.begin()) % 2); });
Обратите внимание, что remove_if передает результат разыменования итератора, и это гарантированно будет reference
согласно Таблице 106 — Требования к итераторам в Стандарте.
Я фактически сделал аккаунт только для этого. Используйте awesomeyi ответ. Это способ чище.
int count = 0;
auto final = std::remove_if (data.begin(), data.end(), [&count](const double d) {
return (count++) % 2;
});
Стандарт гласит, что предикат применяется точно в последний раз. И remove_if работает с ForwardIterators.
Это подразумевает, что предикат применяется только один раз в том же порядке, в котором он первоначально появился в последовательности.
Если, конечно, библиотека контролирует вас, сохраняя внутренние копии ForwardIterator.
Воспользуйтесь тем, что lambas
может захватывать переменные. Быстрый пример:
vector<double> data = {5, 3, 6, 7, 8};
int count = 0;
auto final = std::remove_if (data.begin(), data.end(), [&](const double d) {
bool b = false;
if(count % 2) b = true;
++count;
return b;
});
for(auto beg = data.begin(); beg != final; ++beg)
cout << *beg << endl;
Код напечатает: 5 6 8