ideas icon indicating copy to clipboard operation
ideas copied to clipboard

Удаление элемента вектора за О(1), если не требуется сохранять порядок элементов

Open perfectGenius opened this issue 1 year ago • 11 comments

Копируем последний элемент вектора на место удаляемого и сдвигаем указатель конца на один элемент. Можно назвать что-то типа erase_unordered.

perfectGenius avatar May 08 '24 22:05 perfectGenius

Зачем делать все комбинаторно возможные методы, которые реализуются из различных пар уже существующих методов std::vector? Какая цель? Чтобы что?

tomilov avatar May 08 '24 23:05 tomilov

Поменьше и попроще кода, больше производительность.

perfectGenius avatar May 08 '24 23:05 perfectGenius

Производительность не больше. Ни на такт.

tomilov avatar May 08 '24 23:05 tomilov

Зачем делать все комбинаторно возможные методы

Почему же тогда вместо pop_back просто не делать resize -1?

perfectGenius avatar May 08 '24 23:05 perfectGenius

делать

tomilov avatar May 09 '24 23:05 tomilov

Чтобы понимать, имеется в виду:

std::swap(*it, vec.back());
vec.pop_back();

GitSparTV avatar May 10 '24 09:05 GitSparTV

Чтобы понимать, имеется в виду:

std::swap(*it, vec.back());
vec.pop_back();

*it = std::move(vec.back()); vec.pop_back();

vtopunov avatar May 10 '24 09:05 vtopunov

std::swap(*it, vec.back());
vec.pop_back();

А как же производительность? Т.е. зачем выделять буфер для обмена и копировать удаляемый элемент? Надежда на компилятор, что он поймёт замысел и не станет делать лишнее? Скорее уж что-то типа

вектор[it] = вектор.back());
вектор.pop_back();

Производительность не больше. Ни на такт.

Может оказаться, что компилятор в некоторых случаях не поймёт, что эти две строки можно выполнять параллельно после получения адреса последнего элемента. А если это одна функция, то это будет однозначно. Также может немного повыситься скорость компиляции, т.к. не надо парсить и разбирать лишнее, изучать связи.

perfectGenius avatar May 10 '24 09:05 perfectGenius

Почему не *it = std::move(vec.back());?

GitSparTV avatar May 10 '24 10:05 GitSparTV

move разве автоматически делает pop_back? Если вы про мой пример, то можно и так, у меня пока мало опыта с итераторами.

perfectGenius avatar May 10 '24 10:05 perfectGenius

Не заменит, я только про первую строчку. Копирование не понравилось.

*it = std::move(vec.back());
vec.pop_back();

GitSparTV avatar May 10 '24 11:05 GitSparTV