«Если рабочий хочет хорошо выполнять свою работу, он должен сначала заточить свои инструменты» — Конфуций, «Аналитики Конфуция. Лу Лингун»
титульная страница > программирование > Почему стирание-remove_if оставляет повторяющиеся пары при удалении элементов из std::vector?

Почему стирание-remove_if оставляет повторяющиеся пары при удалении элементов из std::vector?

Опубликовано 23 декабря 2024 г.
Просматривать:810

Why does erase-remove_if leave behind duplicate pairs when removing elements from a `std::vector`?

Идиома Erase-Remove_if для удаления пар

При попытке использовать идиому Erase-Remove_if для удаления пар из std::vector>, возникает своеобразная проблема. Несмотря на то, что пары со значением .first, равным 4, предназначены для удаления, первоначальная реализация оставляет дублирующую пару:

stopPoints.erase(std::remove_if(stopPoints.begin(),
                                stopPoints.end(),
                                [&](const stopPointPair stopPoint)-> bool { return stopPoint.first == 4; }));

Корень проблемы лежит в неполном процессе стирания. std::erase_if сдвигает соответствующие элементы только к концу вектора; он их не удаляет. Чтобы завершить удаление, правильный подход — использовать итератор, возвращаемый std::remove_if, в качестве отправной точки для удаления:

stopPoints.erase(std::remove_if(stopPoints.begin(),
                                stopPoints.end(),
                                [](const stopPointPair stopPoint)-> bool 
                                       { return stopPoint.first == 4; }), 
                 stopPoints.end());

Понимание механизма Erase-Remove_if:

  • Обмен элементами: std::remove_if меняет местами элементы внутри вектора, сдвигая все несовпадающие элементы к началу. Совпадающие элементы оказываются в задней части вектора.
  • Итерация предиката: Лямбда-выражение предиката определяет, какие элементы следует удалить. Если предикат возвращает true, соответствующий элемент перемещается в конец вектора.
  • Извлечение итератора: std::remove_if возвращает итератор, указывающий на первый элемент, соответствующий предикату; этот итератор отмечает начало удаляемых элементов.
  • Стирание вектора: std::vector::erase вызывает операцию стирания диапазона, начиная с возвращенного итератора и распространяясь на вектор конец. На этом этапе из вектора удаляются все совпадающие элементы.

Для получения дополнительной информации обратитесь к статье Википедии о [Идиома стереть-удалить](https://en.wikipedia.org/ wiki/Erase-remove_idiom).

Последний учебник Более>

Изучайте китайский

Отказ от ответственности: Все предоставленные ресурсы частично взяты из Интернета. В случае нарушения ваших авторских прав или других прав и интересов, пожалуйста, объясните подробные причины и предоставьте доказательства авторских прав или прав и интересов, а затем отправьте их по электронной почте: [email protected]. Мы сделаем это за вас как можно скорее.

Copyright© 2022 湘ICP备2022001581号-3