现在位置: 首页 > C++ 教程 > 正文

C++ <vector> erase 函数

C++ 容器类 <vector> C++ 容器类 <vector>


erase 是 vector 中用于删除指定位置元素的函数,是容器中最灵活的删除方式。

erase 是容器类的成员函数,用于删除容器中指定位置的一个或多个元素。它接受迭代器参数。

erase 提供了删除任意位置元素的能力,虽然在 vector 中效率不如 pop_back(需要移动后续元素),但功能更强大。

单词释义erase 表示"擦除",即删除指定位置的元素。


基本语法与参数

erase 是容器类的成员函数,需要指定删除位置的迭代器。

语法格式

// 删除 pos 位置的元素
iterator erase(iterator pos);

// 删除 [first, last) 范围内的所有元素
iterator erase(iterator first, iterator last);

参数说明

  • 参数pos
    • 类型: 迭代器(iterator
    • 描述: 要删除的元素的位置。
    • 参数first, last
      • 类型: 迭代器(iterator
      • 描述: 要删除的元素范围的起始和结束迭代器。删除范围是 [first, last),即包含 first 不包含 last

    函数说明

    • 返回值: 返回指向最后一个被删除元素之后位置的迭代器(即原来 last 位置的元素)。
    • 效果: 删除指定位置的元素,后续元素依次前移。
    • 注意erase 删除元素后,后面的元素会移动到前面,迭代器可能会失效。

    实例

    让我们通过一系列例子,彻底掌握 erase 的用法。

    示例 1:基础用法 - 删除单个元素

    实例

    #include <iostream>
    #include <vector>

    int main() {
        std::vector<int> numbers = {1, 2, 3, 4, 5};

        std::cout << "原始 vector: ";
        for(int n : numbers) std::cout << n << " ";
        std::cout << std::endl;

        // 删除第二个位置(索引 1)的元素
        auto it = numbers.begin() + 1;
        numbers.erase(it);

        std::cout << "删除后: ";
        for(int n : numbers) std::cout << n << " ";
        std::cout << std::endl;

        return 0;
    }

    运行结果预期:

    原始 vector: 1 2 3 4 5
    删除后: 1 3 4 5
    

    代码解析:

    1. numbers.begin() + 1 指向第二个元素(值为 2)。
    2. erase 删除该位置的元素。
    3. 后续元素(3, 4, 5)都向前移动一位。

    示例 2:删除开头和末尾的元素

    使用 begin()end() 可以删除开头和末尾元素。

    实例

    #include <iostream>
    #include <vector>

    int main() {
        std::vector<int> numbers = {10, 20, 30, 40, 50};

        std::cout << "原始: ";
        for(int n : numbers) std::cout << n << " ";
        std::cout << std::endl;

        // 删除第一个元素
        numbers.erase(numbers.begin());
        std::cout << "删除第一个元素后: ";
        for(int n : numbers) std::cout << n << " ";
        std::cout << std::endl;

        // 删除最后一个元素(end() 指向最后一个元素之后)
        numbers.erase(numbers.end() - 1);
        std::cout << "删除最后一个元素后: ";
        for(int n : numbers) std::cout << n << " ";
        std::cout << std::endl;

        return 0;
    }

    运行结果预期:

    原始: 10 20 30 40 50
    删除第一个元素后: 20 30 40 50
    删除最后一个元素后: 20 30 40
    

    代码解析:

    • erase(begin()) 删除第一个元素。
    • erase(end() - 1) 删除最后一个元素(注意 end() 指向最后元素之后)。

    示例 3:删除多个元素(范围)

    可以删除指定范围内的所有元素。

    实例

    #include <iostream>
    #include <vector>

    int main() {
        std::vector<int> numbers = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};

        std::cout << "原始: ";
        for(int n : numbers) std::cout << n << " ";
        std::cout << std::endl;

        // 删除第二个到第五个元素(索引 1 到 4)
        auto first = numbers.begin() + 1;
        auto last = numbers.begin() + 5;
        numbers.erase(first, last);

        std::cout << "删除位置 [1, 5) 后: ";
        for(int n : numbers) std::cout << n << " ";
        std::cout << std::endl;

        return 0;
    }

    运行结果预期:

    原始: 1 2 3 4 5 6 7 8 9 10
    删除位置 [1, 5) 后: 1 6 7 8 9 10
    

    代码解析:

    • erase(first, last) 删除从 firstlast 之前的所有元素。
    • 这里删除了索引 1, 2, 3, 4 的元素(2, 3, 4, 5)。

    示例 4:删除所有奇数

    结合循环可以删除满足条件的元素。

    实例

    #include <iostream>
    #include <vector>

    int main() {
        std::vector<int> numbers = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};

        std::cout << "原始: ";
        for(int n : numbers) std::cout << n << " ";
        std::cout << std::endl;

        // 删除所有奇数
        for(auto it = numbers.begin(); it != numbers.end(); ) {
            if(*it % 2 == 1) { // 如果是奇数
                it = numbers.erase(it); // erase 返回下一个元素的迭代器
            } else {
                ++it;
            }
        }

        std::cout << "删除奇数后: ";
        for(int n : numbers) std::cout << n << " ";
        std::cout << std::endl;

        return 0;
    }

    运行结果预期:

    原始: 1 2 3 4 5 6 7 8 9 10
    删除奇数后: 2 4 6 8 10

    代码解析:

    • 在循环中删除元素时,要注意更新迭代器。
    • erase 返回指向下一个元素的迭代器,这是正确的删除方式。

    示例 5:erase 的效率问题

    在 vector 中使用 erase 删除中间元素效率较低。

    实例

    #include <iostream>
    #include <vector>
    #include <chrono>

    int main() {
        const int N = 10000;

        // 删除开头元素(效率低)
        std::vector<int> v1;
        for(int i = 0; i < N; ++i) v1.push_back(i);

        auto start1 = std::chrono::high_resolution_clock::now();
        while(!v1.empty()) {
            v1.erase(v1.begin());
        }
        auto end1 = std::chrono::high_resolution_clock::now();
        auto duration1 = std::chrono::duration_cast<std::chrono::microseconds>(end1 - start1);

        // 删除末尾元素(效率高)
        std::vector<int> v2;
        for(int i = 0; i < N; ++i) v2.push_back(i);

        auto start2 = std::chrono::high_resolution_clock::now();
        while(!v2.empty()) {
            v2.pop_back();
        }
        auto end2 = std::chrono::high_resolution_clock::now();
        auto duration2 = std::chrono::duration_cast<std::chrono::microseconds>(end2 - start2);

        std::cout << "从开头删除 " << N << " 个元素耗时: " << duration1.count() << " 微秒" << std::endl;
        std::cout << "从末尾删除 " << N << " 个元素耗时: " << duration2.count() << " 微秒" << std::endl;

        return 0;
    }

    代码解析:

    • 从 vector 开头删除元素需要移动所有后续元素,效率很低。
    • 从末尾删除元素(pop_back)不需要移动元素,效率高。
    • 如果需要频繁删除开头元素,考虑使用 dequelist

    示例 6:使用 erase 实现数据过滤

    erase 可以用于过滤数据。

    实例

    #include <iostream>
    #include <vector>
    #include <string>

    // 简单的不及格过滤
    void filterFailing(std::vector<int>& scores) {
        for(auto it = scores.begin(); it != scores.end(); ) {
            if(*it < 60) {
                it = scores.erase(it);
            } else {
                ++it;
            }
        }
    }

    int main() {
        std::vector<int> scores = {85, 92, 45, 78, 55, 90, 67};

        std::cout << "原始成绩: ";
        for(int s : scores) std::cout << s << " ";
        std::cout << std::endl;

        filterFailing(scores);

        std::cout << "及格成绩: ";
        for(int s : scores) std::cout << s << " ";
        std::cout << std::endl;

        return 0;
    }

    运行结果预期:

    原始成绩: 85 92 45 78 55 90 67
    及格成绩: 85 92 78 90 67
    

    代码解析:

    • 使用 erase 可以实现条件过滤。
    • 删除不及格(小于 60 分)的成绩。

    C++ 容器类 <vector> C++ 容器类 <vector>