Я предлагаю несколько методов:
1. Быстрый метод, который не сохраняет первоначальный порядок элементов:
Назначьте текущий последний элемент вектора на удаляемый элемент, затем удалите последний элемент. Это позволит избежать больших движений, и все индексы, кроме последнего, останутся постоянными. Если вы начнете стирать со спины, все предварительно вычисленные индексы будут правильными.
void quickDelete( int idx )
{
vec[idx] = vec.back();
vec.pop_back();
}
Я вижу, что это, по сути, кодированная вручную идиома стирания-удаления, на которую указал Клаим ...
2. Более медленный метод, который сохраняет первоначальный порядок элементов:
Шаг 1. Пометьте все векторные элементы, которые нужно удалить, т. Е. Специальным значением. Здесь есть O (| индексы для удаления |).
Шаг 2: Сотрите все отмеченные элементы, используя v.erase( remove (v.begin(), v.end(), special_value), v.end() );
. Это имеет O (| вектор v |).
Таким образом, общее время выполнения равно O (| vector v |), при условии, что список индексов короче вектора.
3. Еще один более медленный метод, который сохраняет первоначальный порядок элементов:
Используйте предикат и удалите его, как описано в https://stackoverflow.com/a/3487742/280314. Чтобы сделать это эффективным и соблюдая требования
а не «сортировка, а затем линейное стирание со смещением», моя идея состоит в том, чтобы реализовать предикат с использованием хеш-таблицы и настроить индексы, хранящиеся в хеш-таблице, по мере того, как удаление продолжается, возвращая значение true, как предложил Клайм.