跳转至

Vector删除元素

clear删除所有

vector::clear()清空整个vector,同时将size置为0,但capacity不变

std::vector<int> vec{1, 2, 3, 4, 5, 6, 7};
printInfo(vec, "=====原始数据");

vec.clear();
printInfo(vec, "=====clear()后");
=====原始数据
    vector: 1 2 3 4 5 6 7 
    vector size: 7
    vector capacity: 7
=====clear()后
    vector: 
    vector size: 0
    vector capacity: 7

pop_back删除最后一个

void vector::pop_back()用来删除末尾元素,无返回值,同时将size减1,但capacity不变

std::vector<int> vec{1, 2, 3, 4, 5, 6, 7};
printInfo(vec, "=====原始数据");

vec.pop_back();
printInfo(vec, "=====pop_back()后");
=====原始数据
    vector: 1 2 3 4 5 6 7 
    vector size: 7
    vector capacity: 7
=====clear()后
    vector: 1 2 3 4 5 6 
    vector size: 6
    vector capacity: 7

erase

vector::erase(iterator it)通过传入迭代器进行删除,并返回it后一个元素的迭代器,但capacity不变

删除单个

auto new_it = vec.erase(it)

  • 删除it所指的元素
  • 删除后,后续元素会接上来,因此这里会返回新的迭代器,以便继续下去(即it后面那个元素的迭代器)
std::vector<int> vec{1, 4, 3, 2, 2, 5, 2};
printInfo(vec, "=====原始数据");

for(auto it = vec.begin(); it != vec.end(); ) 
    //这里要非常注意,这里不能写++it(有很多博主写错)
    //因为erase的返回值已经更新过了,再++it,会错过一个
{
    if(*it < 3)
    {
        std::cout << std::endl << "=====将要删除元素:" << *it << std::endl;

        it = vec.erase(it); //删除,并更新迭代器

        printInfo(vec, "删除后:");
        std::cout << "\t迭代器指向: ";
        if(it == vec.end())
        {
            std::cout << "末尾" << std::endl;
        }
        else
        {
            std::cout << *it << std::endl;
        }
    }
    else
    {
        ++it; //没有删除,正常位移
    }
}
=====原始数据
    vector: 1 4 3 2 2 5 2 
    vector size: 7
    vector capacity: 7

=====将要删除元素:1
删除后:
    vector: 4 3 2 2 5 2 
    vector size: 6
    vector capacity: 7
    迭代器指向: 4

=====将要删除元素:2
删除后:
    vector: 4 3 2 5 2 
    vector size: 5
    vector capacity: 7
    迭代器指向: 2

=====将要删除元素:2
删除后:
    vector: 4 3 5 2 
    vector size: 4
    vector capacity: 7
    迭代器指向: 5

=====将要删除元素:2
删除后:
    vector: 4 3 5 
    vector size: 3
    vector capacity: 7
    迭代器指向: 末尾

删除某个范围

auto new_it = vec.erase(start_it, end_it)

  • 删除start_it迭代器,到end_it迭代器中间的元素。符合STL的前闭后开原则(会删除start_it所指元素,但不删除end_it所指元素)
  • 返回end_it所指元素,新的迭代器
std::vector<int> vec{1, 2, 3, 4, 5, 6, 7};
printInfo(vec, "=====原始数据");

//往后位移1步,即元素2
auto start_it = vec.begin();
std::advance(start_it, 1); 

//往后位移5步,即元素6
auto end_it = vec.begin();
std::advance(end_it, 5); 

//删除[2, 6)。包括2,不包括6
std::cout << "删除:[" << *start_it << "," << *end_it << ")" << std::endl;

//删除,并更新迭代器
auto it = vec.erase(start_it, end_it); 
printInfo(vec, "=====删除后:"); //1 6 7 

std::cout << "\t迭代器指向: ";
if(it == vec.end())
{
    std::cout << "末尾" << std::endl;
}
else
{
    std::cout << *it << std::endl;
}
=====原始数据
    vector: 1 2 3 4 5 6 7 
    vector size: 7
    vector capacity: 7
删除:[2,6)
=====删除后:
    vector: 1 6 7 
    vector size: 3
    vector capacity: 7
    迭代器指向: 6

附:调试函数printInfo

#include <vector>
#include <iostream>

void printInfo(const std::vector<int>& vec, const std::string& title)
{
    std::cout << title << std::endl;
    std::cout << "\t" << "vector: ";
    for(const auto& item : vec)
    {
        std::cout << item << " ";
    }
    std::cout << std::endl;
    std::cout << "\t" << "vector size: " << vec.size() << std::endl;
    std::cout << "\t" << "vector capacity: " << vec.capacity() << std::endl;
}