У меня есть std::vector<int>
и второй контейнер, содержащий итераторы или индексы (без ключей, я хочу постоянного доступа к элементу) к этому вектору для целей удаления.
Предположим, что у меня есть вектор из 1000 элементов и вы хотите стереть 200 из них. Порядок удаленных элементов должен быть таким же после операций удаления, как и раньше.
Еще одна вещь, которую я пропустил в первой версии моего вопроса: значения уникальны. Они являются тождествами.
Как вы это сделаете в безопасном (в отношении правил stl) и эффективным образом (решение для вектора должно быть окончательным)?
Возможности или Методы, о которых я думал:
- erase-remove idiom (http://en.wikipedia.org/wiki/Erase-remove_idiom): первоначально для удаления элементов, которые выполняют условие (включая линейный поиск), но я подумайте с диапазонами размеров 1, этот метод можно было бы использовать с уже предоставленными итераторами и фиктивным состоянием. Вопрос: является ли первоначальный порядок сохраненных элементов и является ли он более эффективным, чем последний метод?
- перебирать индексы и стирать элементы с помощью
vector.erase(vector.begin()+index+offset)
, сохраняя при этом индексы в контейнере для вычисления смещения. Это смещение может быть определено для каждой итерации удаления с использованиемstd::lower_bound
n контейнера уже удаленных элементов. Проблема: много бинарных_значений для получения смещения и большого количества операций перемещения из-за удаления случайного местоположения. - В настоящий момент я делаю следующее: получаю все итераторы для удаляемых элементов. Сортируйте их в порядке убывания в соответствии с местоположением в векторе и обведите их над окончательным удалением с помощью
vector.erase
. Теперь я не признал недействительным какой-либо итератор, и нет никаких операций перегруппировки векторов, кроме самого удаления. Проблема: много сортировки
Итак, как бы вы справились с этим? Любые новые идеи? Любые рекомендации?
Спасибо за ваш вклад.
Саша
Изменить/обновить/Собственные результаты: Я реализовал erase-remove idiom, о котором также упоминал KennyTM, с предикатом , основанный на поиске в boost:: dynamic_bitset и безумно быстро. Кроме того, я попробовал метод PigBen move-and-truncate (также упоминаемый Стивом Джессопом), который также обращается к битете в нем while-loop. Оба кажутся одинаково быстрыми с моими данными. Я попытался удалить 100 из 1000 элементов (unsigned ints), сделал это 100 удалений 1M раз, и не было существенной разницы. Поскольку я думаю, что stl-based erase-remove idiom более естественна, я выбираю этот метод (аргумент также упоминался KennyTM).