STL标准模块库操作

这三个方法通常处理集合类数据(如 vector, string, 哈希表等)。

以下是它们在 C++ 中的核心区别和用法:

  1. insert() ------ 插入元素

最通用的方法,用于将一个或多个元素插入到容器的指定位置(对于序列容器如 vector)或直接插入(对于关联容器如 set, map)。

对 vector / string 等:在迭代器位置前插入,后续元素后移。

复制代码
std::vector<int> v = {1, 2, 3};
v.insert(v.begin() + 1, 99);  // 在第二个位置插入99 → {1, 99, 2, 3}

对 set / map:根据键自动排序,只需提供值或键值对。

复制代码
std::set<int> s = {1, 2};
s.insert(3);  // s → {1, 2, 3}(自动排序)
  1. reserve() ------ 预留空间

只对 vector 和 string 这类连续存储的容器有意义。它的作用是提前分配好内存,以避免在后续添加元素时反复扩容(扩容通常需要复制全部元素,开销很大)。

重要:reserve() 只改变容器的 capacity(容量),不改变 size(实际元素个数)。

效果:如果你知道最终会有 1000 个元素,先用 v.reserve(1000);,那么添加 1000 个元素的过程中只会进行 0 次内存重分配,否则可能要重分配 10 次以上。

复制代码
std::vector<int> v;
v.reserve(1000);   // 预留1000个元素的空间
for (int i = 0; i < 1000; ++i) v.push_back(i); // 不会触发扩容
  1. assign() ------ 重新赋值

它会清空容器原有的所有内容,然后用新指定的元素替换。可以理解为"先清除,后插入"。

常见用法:

用 n 个 val 填充:

复制代码
std::vector<int> v = {1, 2, 3};
v.assign(5, 42);   // v → {42, 42, 42, 42, 42}

用另一个容器的迭代器区间赋值:

复制代码
std::vector<int> src = {10, 20, 30};
std::vector<int> dst;
dst.assign(src.begin(), src.end());  // dst → {10, 20, 30}

/************************************************************************************/

1.vector - 动态数组

特点:连续内存,支持随机访问,尾部插入/删除快,中间/头部慢。

适用:需要频繁随机访问,主要在尾部操作。

复制代码
#include <iostream>
#include <vector>
using namespace std;

int main() {
    // 1. 构造与赋值
    vector<int> v1;                           // 空 vector
    vector<int> v2(5, 10);                    // {10,10,10,10,10}
    vector<int> v3 = {1, 2, 3, 4, 5};         // 初始化列表
    vector<int> v4(v3.begin(), v3.end());     // 迭代器区间构造
    
    v1.assign(3, 7);                          // {7,7,7}
    v1 = {1, 2, 3};                           // {1,2,3}
    
    // 2. 容量
    cout << "size: " << v1.size() << ", capacity: " << v1.capacity() << endl;
    v1.reserve(100);                          // 预留100个位置
    cout << "after reserve, capacity: " << v1.capacity() << endl;
    
    // 3. 访问
    v1[0] = 10;
    v1.at(1) = 20;
    cout << "front: " << v1.front() << ", back: " << v1.back() << endl;
    
    // 4. 尾部插入/删除(高效)
    v1.push_back(30);                         // {10,20,3,30}
    v1.emplace_back(40);                      // {10,20,3,30,40}
    v1.pop_back();                            // {10,20,3,30}
    
    // 5. 中间插入/删除(低效 O(n))
    auto it = v1.begin() + 2;
    v1.insert(it, 100);                       // 在索引2位置插入100
    v1.erase(v1.begin());                     // 删除第一个元素
    
    // 6. 遍历
    cout << "Elements: ";
    for (int x : v1) {
        cout << x << " ";
    }
    cout << endl;
    
    // 7. 清空与交换
    v1.clear();                               // 清空所有元素
    cout << "After clear, size: " << v1.size() << endl;
    
    v3.swap(v2);                              // 交换 v3 和 v2
    cout << "v3 after swap: ";
    for (int x : v3) cout << x << " ";        // {10,10,10,10,10}
    cout << endl;
    
    return 0;
}

//任意位置操作

复制代码
#include <iostream>
#include <vector>
#include <string>

using namespace std;

// 辅助函数:打印 vector 内容
void print(const vector<int>& v, const string& msg = "") {
    cout << msg;
    for (int x : v) {
        cout << x << " ";
    }
    cout << endl;
}

int main() {
    // ========== 1. insert 插入单个元素 ==========
    vector<int> v1 = {1, 2, 3, 4, 5};
    print(v1, "初始: ");
    
    // 在开头插入 99
    v1.insert(v1.begin(), 99);
    print(v1, "开头插入99: ");
    
    // 在第三个位置(索引2)插入 88
    v1.insert(v1.begin() + 2, 88);
    print(v1, "索引2插入88: ");
    
    // 在末尾插入 77
    v1.insert(v1.end(), 77);
    print(v1, "末尾插入77: ");
    
    cout << endl;
    
    // ========== 2. insert 插入多个相同元素 ==========
    vector<int> v2 = {10, 20, 30};
    print(v2, "初始: ");
    
    // 在第二个位置插入 3 个 99
    v2.insert(v2.begin() + 1, 3, 99);
    print(v2, "索引1插入3个99: ");
    
    cout << endl;
    
    // ========== 3. insert 插入另一个容器的区间 ==========
    vector<int> v3 = {1, 2, 3};
    vector<int> v4 = {100, 200, 300};
    print(v3, "v3初始: ");
    print(v4, "v4: ");
    
    // 将 v4 的全部元素插入到 v3 的第二个位置
    v3.insert(v3.begin() + 1, v4.begin(), v4.end());
    print(v3, "v3插入v4后: ");
    
    cout << endl;
    
    // ========== 4. insert 插入初始化列表 ==========
    vector<int> v5 = {1, 2, 3};
    print(v5, "初始: ");
    
    // 在末尾插入 {10, 20, 30}
    v5.insert(v5.end(), {10, 20, 30});
    print(v5, "末尾插入列表: ");
    
    cout << endl;
    
    // ========== 5. emplace 直接构造(避免临时对象) ==========
    vector<pair<int, string>> v6;
    v6.push_back({1, "one"});      // 传统方式:需要临时对象
    v6.emplace_back(2, "two");     // 尾部直接构造
    
    // 在开头直接构造 pair
    v6.emplace(v6.begin(), 0, "zero");
    
    cout << "emplace 结果: ";
    for (const auto& p : v6) {
        cout << "(" << p.first << "," << p.second << ") ";
    }
    cout << endl << endl;
    
    // ========== 6. erase 删除单个元素 ==========
    vector<int> v7 = {10, 20, 30, 40, 50, 60};
    print(v7, "初始: ");
    
    // 删除第一个元素
    v7.erase(v7.begin());
    print(v7, "删除第一个: ");
    
    // 删除第三个元素(索引2)
    v7.erase(v7.begin() + 2);
    print(v7, "删除第三个: ");
    
    // 删除最后一个元素
    v7.erase(v7.end() - 1);
    print(v7, "删除最后一个: ");
    
    cout << endl;
    
    // ========== 7. erase 删除区间 ==========
    vector<int> v8 = {10, 20, 30, 40, 50, 60, 70, 80};
    print(v8, "初始: ");
    
    // 删除前3个元素 [begin, begin+3)
    v8.erase(v8.begin(), v8.begin() + 3);
    print(v8, "删除前3个: ");
    
    // 删除最后2个元素 [end-2, end)
    v8.erase(v8.end() - 2, v8.end());
    print(v8, "删除最后2个: ");
    
    // 删除中间一段 [begin+1, begin+3)
    v8.erase(v8.begin() + 1, v8.begin() + 3);
    print(v8, "删除索引1到2: ");
    
    cout << endl;
    
    // ========== 8. erase 返回值(指向被删除元素的下一个位置) ==========
    vector<int> v9 = {1, 2, 3, 4, 5, 6};
    print(v9, "初始: ");
    
    // 删除所有偶数
    auto it = v9.begin();
    while (it != v9.end()) {
        if (*it % 2 == 0) {
            it = v9.erase(it);  // erase 返回下一个有效迭代器
        } else {
            ++it;
        }
    }
    print(v9, "删除所有偶数后: ");
    
    cout << endl;
    
    // ========== 9. 组合使用:insert + erase ==========
    vector<int> v10 = {1, 2, 3, 4, 5};
    print(v10, "初始: ");
    
    // 将第三个元素(索引2)移动到开头
    int temp = v10[2];
    v10.erase(v10.begin() + 2);
    v10.insert(v10.begin(), temp);
    print(v10, "将第三个元素移到开头: ");
    
    // 将最后一个元素插入到第二个位置
    int last = v10.back();
    v10.pop_back();  // 或 v10.erase(v10.end() - 1)
    v10.insert(v10.begin() + 1, last);
    print(v10, "将最后一个元素插入到第二个位置: ");
    
    return 0;
}
  1. list - 双向链表

特点:非连续内存,不支持随机访问,任何位置插入/删除都快。

适用:需要频繁在中间插入/删除。

复制代码
#include <list>
#include <iostream>

int main() {
    std::list<int> lst;
    
    // 添加元素
    lst.push_back(10);
    lst.push_front(5);
    lst.push_back(20);
    // lst: {5, 10, 20}
    
    // 不支持随机访问(不能写 lst[1])
    // 只能通过迭代器访问
    for (int x : lst) {
        std::cout << x << " ";
    }
    // 输出:5 10 20
    
    // 在中间插入(O(1) 时间复杂度)
    auto it = lst.begin();
    ++it;  // 指向第二个元素(10)
    lst.insert(it, 7);  // {5, 7, 10, 20}
    
    // 删除元素
    lst.remove(10);  // 删除所有值为10的节点 → {5, 7, 20}
    
    return 0;
}
  1. deque - 双端队列

特点:分段连续内存,支持随机访问,头尾插入/删除都快。

适用:需要在头尾两端频繁操作。

复制代码
#include <deque>
#include <iostream>

int main() {
    std::deque<int> dq;
    
    // 两端添加
    dq.push_back(20);
    dq.push_front(10);
    dq.push_back(30);
    // dq: {10, 20, 30}
    
    // 支持随机访问
    std::cout << dq[1] << std::endl;  // 输出 20
    
    // 两端删除
    dq.pop_front();  // {20, 30}
    dq.pop_back();   // {20}
    
    return 0;
}
  1. set - 集合(唯一、有序)

特点:元素唯一且自动升序排列。

复制代码
#include <set>
#include <iostream>

int main() {
    std::set<int> s;
    
    // 插入元素
    s.insert(5);
    s.insert(2);
    s.insert(8);
    s.insert(5);  // 重复,不会插入
    
    // 自动排序
    for (int x : s) {
        std::cout << x << " ";
    }
    // 输出:2 5 8
    
    // 查找元素
    if (s.find(5) != s.end()) {
        std::cout << "Found 5" << std::endl;
    }
    
    // 删除元素
    s.erase(2);  // {5, 8}
    
    return 0;
}
  1. map - 键值对映射(有序)

特点:每个键唯一,按键自动排序。

复制代码
#include <map>
#include <iostream>

int main() {
    std::map<std::string, int> age;
    
    // 插入键值对
    age["Alice"] = 25;
    age["Bob"] = 30;
    age.insert({"Charlie", 28});
    
    // 访问
    std::cout << "Alice's age: " << age["Alice"] << std::endl;
    
    // 遍历(按键排序)
    for (const auto& [name, years] : age) {
        std::cout << name << ": " << years << std::endl;
    }
    // 输出:Alice: 25, Bob: 30, Charlie: 28
    
    // 查找
    if (age.find("Bob") != age.end()) {
        std::cout << "Bob found" << std::endl;
    }
    
    return 0;
}

unordered_set - 无序集合

复制代码
#include <unordered_set>
#include <iostream>

int main() {
    std::unordered_set<int> us;
    
    us.insert(5);
    us.insert(2);
    us.insert(8);
    us.insert(5);  // 重复无效
    
    // 输出顺序不确定(哈希决定)
    for (int x : us) {
        std::cout << x << " ";
    }
    // 可能输出:8 2 5 或其他顺序
    
    return 0;
}

unordered_map - 无序映射

复制代码
#include <unordered_map>
#include <iostream>

int main() {
    std::unordered_map<std::string, int> scores;
    
    scores["Alice"] = 95;
    scores["Bob"] = 87;
    scores["Charlie"] = 92;
    
    // 遍历(顺序不确定)
    for (const auto& [name, score] : scores) {
        std::cout << name << ": " << score << std::endl;
    }
    
    return 0;
}
相关推荐
Song_da_da_1 小时前
C# 接口(Interface)深度解析:规范、解耦与灵活扩展
开发语言·c#
政沅同学1 小时前
基于 C# WPF + HALCON 的工业视觉算法工具框架(开源)
开发语言·c#·wpf
影寂ldy1 小时前
C#WinForm 窗体基础(入口、部分类、属性、生命周期事件)
开发语言·c#
2301_781833521 小时前
Python 正则表达式入门教程
开发语言·python·正则表达式
gihigo19982 小时前
基于蒙特卡洛的异常值剔除(RANSAC + MC置信区间)—MATLAB实现
开发语言·算法·matlab
2601_958352902 小时前
双麦 DSP 音频拾音模块 A-68:多场景远场语音交互的声学解决方案
嵌入式硬件·音视频·降噪·回音消除·音频处理模块
Ting.~2 小时前
在java中接入百度地图
java·开发语言·dubbo
小短腿的代码世界2 小时前
Qt对象树析构链与智能指针协同:零泄漏内存管理架构
开发语言·qt·架构
zhaqonianzhu2 小时前
LOL切回桌面问题,采用监控抓出元凶方式
开发语言