Как стереть элемент из std :: vector <> по индексу? - PullRequest
437 голосов
/ 17 мая 2009

У меня есть std :: vector , и я хочу удалить n-й элемент. Как мне это сделать?

std::vector<int> vec;

vec.push_back(6);
vec.push_back(-17);
vec.push_back(12);

vec.erase(???);

Ответы [ 12 ]

602 голосов
/ 17 мая 2009

Чтобы удалить один элемент, вы можете сделать:

std::vector<int> vec;

vec.push_back(6);
vec.push_back(-17);
vec.push_back(12);

// Deletes the second element (vec[1])
vec.erase(vec.begin() + 1);

Или, чтобы удалить более одного элемента одновременно:

// Deletes the second through third elements (vec[1], vec[2])
vec.erase(vec.begin() + 1, vec.begin() + 3);
189 голосов
/ 17 мая 2009

Метод стирания в std :: vector перегружен, поэтому, вероятно, яснее вызвать

vec.erase(vec.begin() + index);

когда вы хотите стереть только один элемент.

50 голосов
/ 10 марта 2011
template <typename T>
void remove(std::vector<T>& vec, size_t pos)
{
    std::vector<T>::iterator it = vec.begin();
    std::advance(it, pos);
    vec.erase(it);
}
14 голосов
/ 04 мая 2016

Метод erase будет использоваться двумя способами:

  1. Стирание одного элемента:

    vector.erase( vector.begin() + 3 ); // Deleting the fourth element
    
  2. Стирание диапазона элементов:

    vector.erase( vector.begin() + 3, vector.begin() + 5 ); // Deleting from fourth element to sixth element
    
6 голосов
/ 18 сентября 2017

Если у вас есть неупорядоченный вектор, вы можете воспользоваться тем, что он неупорядочен, и использовать то, что я видел у Дэна Хиггинса на CPPCON

template< typename TContainer >
static bool EraseFromUnorderedByIndex( TContainer& inContainer, size_t inIndex )
{
    if ( inIndex < inContainer.size() )
    {
        if ( inIndex != inContainer.size() - 1 )
            inContainer[inIndex] = inContainer.back();
        inContainer.pop_back();
        return true;
    }
    return false;
}

Поскольку порядок списка не имеет значения, просто возьмите последний элемент в списке и скопируйте его поверх элемента, который вы хотите удалить, затем вытолкните и удалите последний элемент.

6 голосов
/ 21 мая 2016

На самом деле, функция erase работает для двух профилей:

  • Удаление одного элемента

    iterator erase (iterator position);
    
  • Удаление диапазона элементов

    iterator erase (iterator first, iterator last);
    

Поскольку std :: vec.begin () отмечает начало контейнера, и если мы хотим удалить i-й элемент в нашем векторе, мы можем использовать:

vec.erase(vec.begin() + index);

Если вы посмотрите внимательно, vec.begin () - это просто указатель на начальную позицию нашего вектора, и добавление к нему значения i увеличивает указатель на позицию i, поэтому вместо этого мы можем получить доступ к указателю на i-й элемент по:

&vec[i]

Итак, мы можем написать:

vec.erase(&vec[i]); // To delete the ith element
4 голосов
/ 12 мая 2016

Если вы работаете с большими векторами (размером> 100 000) и хотите удалить много элементов, я бы порекомендовал сделать что-то вроде этого:

int main(int argc, char** argv) {

    vector <int> vec;
    vector <int> vec2;

    for (int i = 0; i < 20000000; i++){
        vec.push_back(i);}

    for (int i = 0; i < vec.size(); i++)
    {
        if(vec.at(i) %3 != 0)
            vec2.push_back(i);
    }

    vec = vec2;
    cout << vec.size() << endl;
}

Код берет каждое число в vec, которое нельзя разделить на 3, и копирует его в vec2. После этого он копирует vec2 в vec. Это довольно быстро. Для обработки 20 000 000 элементов этот алгоритм занимает всего 0,8 с!

Я сделал то же самое с методом стирания, и это занимает много-много времени:

Erase-Version (10k elements)  : 0.04 sec
Erase-Version (100k elements) : 0.6  sec
Erase-Version (1000k elements): 56   sec
Erase-Version (10000k elements): ...still calculating (>30 min)
2 голосов
/ 19 июня 2016

Чтобы удалить элемент, используйте следующий способ:

// declaring and assigning array1 
std:vector<int> array1 {0,2,3,4};

// erasing the value in the array
array1.erase(array1.begin()+n);

Для более широкого обзора вы можете посетить: http://www.cplusplus.com/reference/vector/vector/erase/

0 голосов
/ 24 июня 2019

Как насчет этого?

void squeeze(vector<int> &v)
{
    int j = 0;
    for (int i = 1; i < v.size(); i++)
        if (v[i] != v[j] && ++j != i)
            v[j] = v[i];
    v.resize(j + 1);
}
0 голосов
/ 26 апреля 2019

самый быстрый способ (для программирования соревнований по сложности времени () = константа)

может стереть 100М элемент за 1 секунду;

    vector<int> it = (vector<int>::iterator) &vec[pos];
    vec.erase(it);

и наиболее читаемый способ: vec.erase(vec.begin() + pos);

...