Удалить неправильно

std::vector<int> v = {1,2,3,4,5};
auto i = std::remove(v.begin(),v.end(),3); 
for(auto j = v.begin(); j!= v.end();++j)
   std::cout << *j;

Фактический выход: 12455

Откуда берутся дополнительные 5?

Требуемый вывод: 1245

Как добиться того же?

Я действительно хочу, чтобы размер вектора менялся, ответ, данный Prasoon saurav выглядит корректно

Ответы

Ответ 1

remove фактически не удаляет элементы

Удалить удаляет из диапазона [first, last) все элементы, которые равны value. То есть remove возвращает итератор new_last, так что диапазон [first, new_last) не содержит элементов, равных value. 1 Итераторы в диапазоне [new_last, last) все все еще разыскиваются, но элементы, на которые они указывают, являются неопределенные. Удалить является стабильным, что означает, что относительный порядок элементов, которые не равны значению, не изменяется. `

std::remove алгоритм работает только с использованием пары передовых итераторов и вообще ничего не знает о базовом контейнере.

Вам нужно использовать erase-remove idiom для на самом деле удалить элемент, т.е. объединить erase с remove

auto i = std::remove(v.begin(),v.end(),3);
v.erase(i,v.end());
for(auto j = v.begin(); j!= v.end();++j)
   std::cout << *j;

Ответ 2

Снова прочитайте документацию для std::remove.

Функция не удаляет элементы из контейнера (фактически, он даже не знает, что задействован контейнер, поскольку он видит только итераторы), он просто перемещает значения в последовательности и возвращает новый итератор i так что весь интервал [ begin .. i [ содержит все неиспользуемые элементы в исходном порядке. Элементы, оставшиеся в [ i .. end [, не указаны, и вы несете ответственность за удаление этого интервала из контейнера (если вам это нужно):

auto i = std::remove(...);
v.erase(i,v.end());

Причина, по которой у вас есть дополнительный 5, заключается в том, что типичный алгоритм удаления копирует значения в отверстия, оставшиеся от удаленных значений, и поскольку значения, прошедшие после итератора i, никогда не перезаписываются, они остаются такими же, как в исходной последовательности, Однако это поведение не является надежным - просто удалите значения i без их чтения.

Ответ 3

remove возвращает новый конец. Итак, исправление вашего кода таково:

 std::vector<int> v = {1,2,3,4,5};
 auto newEnd = std::remove(v.begin(),v.end(),3);//return value stored in newEnd
 for(auto j = v.begin(); j!= newEnd ;++j) //note j!=newEnd
     std::cout << *j;

Вывод:

1245

Проверьте сами: http://www.ideone.com/3AMD9

Ответ 4

Это означает, что вы печатаете позицию n + 1 вектора в инструкции for(). Это должно быть:

for(auto j = v.begin(); j!= v.end();j++)
   std::cout << *j;

j++ no ++j