Стереть указанный элемент c из вектора не работает - PullRequest
3 голосов
/ 14 марта 2020
// erasing from vector
#include <iostream>
#include <vector>

int main ()
{
  std::vector<int> myvector;

  // set some values (from 1 to 10)
  for (int i=1; i<=10; i++) myvector.push_back(i);

  //First for loop
  for(int i=myvector.size()-1;i>=0;i--)
  {
      myvector.erase(myvector.begin()+i);
  }

  //second for loop which isn't working 

//   for(int i=0;i<myvector.size();i++)
//   {
//       myvector.erase(myvector.begin()+i);
//   }



  std::cout << "myvector contains:";
  for (unsigned i=0; i<myvector.size(); ++i)
    std::cout << ' ' << myvector[i];
  std::cout << '\n';

  return 0;
}

В этом коде у меня есть два цикла for, которые делают одно и то же. Первый работает, в то время как второй, который закомментирован, не работает, и вывод, если я использовал закомментированный для l oop:

myvector contains: 2 4 6 8 10                                                                                             

Есть идеи, почему это происходит?

Ответы [ 2 ]

4 голосов
/ 14 марта 2020

Это потому, что в условии, которое вы называете myvector.size(), будет возвращаться все меньшее и меньшее число, поскольку ваш вектор уменьшается с каждой итерацией.

В первой версии вы вызываете его только один раз для инициализации i Вот почему нет проблем. Но во второй версии он вызывается в каждой итерации.

1 голос
/ 14 марта 2020

std::vector::erase удаляет элемент (ы) в заданном диапазоне [first, last) или в заданной позиции (версия, которую вы используете) и вызывает оператор присваивания для каждого элемента после удаленного элемент, чтобы «сдвинуть его вниз».

Рассмотрим std::vector, который выглядит следующим образом:

[ a0 | a1 | a2 | a3 | a4 | a5 | a6 ]

На первой итерации l oop вы стираете элемент в вектор в позиции 0, который преобразует вектор следующим образом:

[ a0 | a1 | a2 | a3 | a4 | a5 | a6 ] --> [ a1 | a2 | a3 | a4 | a5 | a6 ]
  ^
  |
  erase at position 0

На второй итерации l oop вы стираете элемент вектора в позиции 1, который преобразует вектор следующим образом:

[ a1 | a2 | a3 | a4 | a5 | a6 ] --> [ a1 | a3 | a4 | a5 | a6 ]
       ^
       |
       erase at position 1

Обратите внимание, что мы «пропустили» элемент a1, который изначально находился в позиции 1 в векторе.

Поскольку каждая итерация l oop представляет собой комбинацию:

  1. Стирание элемента (смещение всего над ним вниз) и
  2. Увеличение индекса

Мы будем пропускать каждый элемент, пока не достигнем конца (или далее).


Если вы хотите стереть канун ry элемент в std::vector, у вас есть несколько вариантов.

Вы можете настроить вашу переменную l oop всякий раз, когда вы найдете элемент для удаления. Поскольку все элементы смещены вниз на один, вы хотите сместить вашу переменную l oop на единицу , если вы что-то сотрете.

for (int i = 0; i < myvector.size(); ++i)
{
    myvector.erase(myvector.begin() + i);
    // if we erased an element, decrement the loop variable
    --i;
}

Если вы знаете диапазон элементов, который вы Если вы хотите erase, вы можете позвонить erase в этом диапазоне:

myvector.erase(myvector.begin(), myvector.end());

Если вы хотите erase всех элементов в vector, вы можете позвонить clear.

myvector.clear();

Если вы хотите удалить все элементы, которые соответствуют определенным критериям поиска, вы можете использовать идиому remove - erase. Мы используем remove, чтобы переместить все элементы, которые соответствуют критериям (удаления), в конец контейнера (но фактически не удаляют их - я знаю, что это интуитивно понятно) remove возвращает итератор в начало этих «удаленных» элементы. Затем вы вызываете erase в диапазоне этого возвращенного итератора до конца старого контейнера.

// This will remove/erase all elements in the vector that are greater than 5
myvector.erase(std::remove_if(myvector.begin(), 
                              myvector.end(),
                              [](int x){return x > 5;}),
               myvector.end());
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...