Стирание элементов от вектора

94
задан NO_NAME 1 August 2015 в 23:37
поделиться

5 ответов

Используйте эти , удаляют/стирают идиому :

std::vector<int>& vec = myNumbers; // use shorter name
vec.erase(std::remove(vec.begin(), vec.end(), number_in), vec.end());

то, Что происходит, - то, что remove уплотняет элементы, которые отличаются от значения, которое будет удалено (number_in) в начале vector, и возвращает итератор первому элементу после того диапазона. Тогда erase удаляет эти элементы (кто значение, является неуказанным).

154
ответ дан Fabio says Reinstate Monica 24 November 2019 в 06:03
поделиться

Вызов стирания будет делать недействительным итераторы, Вы могли использовать:

void erase(std::vector<int>& myNumbers_in, int number_in)
{
    std::vector<int>::iterator iter = myNumbers_in.begin();
    while (iter != myNumbers_in.end())
    {
        if (*iter == number_in)
        {
            iter = myNumbers_in.erase(iter);
        }
        else
        {
           ++iter;
        }
    }

}

Или Вы могли использовать станд.:: remove_if вместе с функтором и станд.:: вектор:: стирание:

struct Eraser
{
    Eraser(int number_in) : number_in(number_in) {}
    int number_in;
    bool operator()(int i) const
    {
        return i == number_in;
    }
};

std::vector<int> myNumbers;
myNumbers.erase(std::remove_if(myNumbers.begin(), myNumbers.end(), Eraser(number_in)), myNumbers.end());

Вместо того, чтобы писать Ваш собственный функтор в этом случае Вы могли использовать станд.:: удалите :

std::vector<int> myNumbers;
myNumbers.erase(std::remove(myNumbers.begin(), myNumbers.end(), number_in), myNumbers.end());
48
ответ дан dalle 24 November 2019 в 06:03
поделиться
  1. можно выполнить итерации использования индексного доступа,

  2. Для предотвращения O (n^2) сложность, можно использовать два индекса, меня - текущий индекс тестирования, j - индексируют для хранения следующего объекта и в конце цикла новый размер вектора.

код:

void erase(std::vector<int>& v, int num)
{
  size_t j = 0;
  for (size_t i = 0; i < v.size(); ++i) {
    if (v[i] != num) v[j++] = v[i];
  }
  // trim vector to new size
  v.resize(j);
}

В таком случае у Вас нет лишения законной силы итераторов, сложность является O (n), и код очень краток, и Вы не должны писать некоторые классы помощника, хотя в некотором случае с помощью классов помощника может извлечь выгоду в более гибком коде.

Этот код не использует erase метод, но решает Вашу задачу.

Используя чистый stl можно сделать это следующим образом (это подобно ответу Motti):

#include <algorithm>

void erase(std::vector<int>& v, int num) {
    vector<int>::iterator it = remove(v.begin(), v.end(), num);
    v.erase(it, v.end());
}
12
ответ дан Patryk 24 November 2019 в 06:03
поделиться

В зависимости от того, почему Вы делаете это, с помощью станд.:: набор мог бы быть лучшей идеей, чем станд.:: вектор.

Это позволяет каждому элементу происходить только однажды. Если Вы добавите его многократно, только будет один экземпляр для стирания так или иначе. Это сделает операцию стирания тривиальной. Операция стирания будет также иметь более низкую временную сложность, чем на векторе, однако, добавление, что элементы медленнее на съемочной площадке, таким образом, это не могла бы быть большая часть преимущества.

Это, конечно, не будет работать, если Вы будете интересоваться тем, сколько раз элемент был добавлен к Вашему вектору или порядку, элементы были добавлены.

3
ответ дан Laserallan 24 November 2019 в 06:03
поделиться

Для стирания 1-го элемента, можно использовать:

vector<int> mV{ 1, 2, 3, 4, 5 }; 
vector<int>::iterator it; 

it = mV.begin(); 
mV.erase(it); 
0
ответ дан 24 November 2019 в 06:03
поделиться
Другие вопросы по тегам:

Похожие вопросы: