C++ STL 容器全解析

开发板推荐:天空星STM32F407VET6开发板

超高性价比 STM32主控 | 超高主频 | 一板兼容百芯 | 比赛神器 | 沉金彩色丝印

  • STL是 C++ 标准库的核心组成部分,其中容器作为 STL 的重要组件,为数据存储和管理提供了高效、通用的解决方案。本文将全面解析 C++ 中常用的 STL 容器(vector、string、deque、stack、queue、list、set、map)。

1. vector 容器:动态数组

基础介绍

vector是 STL 中最常用的动态数组容器,底层基于连续内存空间实现。它支持随机访问(效率 O (1)),尾部插入 / 删除元素效率高(O (1)),中间插入 / 删除效率低(O (n)),可自动扩容。

核心功能实现

(1)构造函数
#include <iostream>
#include <vector>
using namespace std;

// 构造函数演示
void testVectorConstruct() {
    // 空构造
    vector<int> v1;
    // 构造n个相同元素
    vector<int> v2(5, 10); // 5个10
    // 区间构造
    vector<int> v3(v2.begin(), v2.end());
    // 拷贝构造
    vector<int> v4(v3);
}
(2)赋值操作
// 赋值操作演示
void testVectorAssign() {
    vector<int> v1(3, 1);
    vector<int> v2;
    // operator=赋值
    v2 = v1;
    vector<int> v3;
    // 区间赋值
    v3.assign(v2.begin(), v2.end());
    vector<int> v4;
    // n个值赋值
    v4.assign(5, 100); // 5个100
}
(3)容量与大小
// 容量和大小演示
void testVectorCapacity() {
    vector<int> v(5, 2);
    // 判断是否为空
    if (v.empty()) {
        cout << "vector为空" << endl;
    } else {
        cout << "vector不为空,容量:" << v.capacity() << " 大小:" << v.size() << endl;
    }
    // 重新指定大小(缩小)
    v.resize(3);
    cout << "resize(3)后大小:" << v.size() << endl;
    // 重新指定大小(扩大,填充默认值)
    v.resize(6);
    cout << "resize(6)后大小:" << v.size() << endl;
    // 重新指定大小(扩大,填充指定值)
    v.resize(8, 9);
    cout << "resize(8,9)后大小:" << v.size() << endl;
}
(4)插入与删除
// 插入和删除演示
void testVectorInsertErase() {
    vector<int> v;
    // 尾插
    v.push_back(10);
    v.push_back(20);
    // 尾删
    v.pop_back();
    // 插入(第一个参数是迭代器)
    v.insert(v.begin(), 30); // 头部插入30
    v.insert(v.begin() + 1, 2, 40); // 第二个位置插入2个40
    // 删除(迭代器)
    v.erase(v.begin()); // 删除头部元素
    // 清空
    // v.clear();
}
(5)元素访问
// 元素访问演示
void testVectorAccess() {
    vector<int> v(5, 10);
    // []访问
    cout << "v[0] = " << v[0] << endl;
    // at访问
    cout << "v.at(1) = " << v.at(1) << endl;
    // 获取第一个元素
    cout << "front: " << v.front() << endl;
    // 获取最后一个元素
    cout << "back: " << v.back() << endl;
}
(6)容器互换与预留空间
// 容器互换和预留空间演示
void testVectorSwapReserve() {
    vector<int> v1(100000, 1);
    cout << "v1容量:" << v1.capacity() << " 大小:" << v1.size() << endl;
    // 收缩空间(匿名对象交换)
    vector<int>(v1).swap(v1);
    cout << "收缩后v1容量:" << v1.capacity() << " 大小:" << v1.size() << endl;

    vector<int> v2;
    // 预留空间(避免频繁扩容)
    v2.reserve(100000);
    int num = 0; // 统计扩容次数
    int* p = nullptr;
    for (int i = 0; i < 100000; i++) {
        v2.push_back(i);
        if (p != &v2[0]) {
            p = &v2[0];
            num++;
        }
    }
    cout << "v2扩容次数:" << num << endl;
}
        vector 综合测试代码
#include <iostream>
#include <vector>
using namespace std;

int main() {
    // 1. 构造
    vector<int> v1;
    vector<int> v2(5, 10);
    vector<int> v3(v2.begin(), v2.end());
    vector<int> v4(v3);

    // 2. 赋值
    vector<int> v5;
    v5 = v4;
    vector<int> v6;
    v6.assign(v5.begin(), v5.end());
    vector<int> v7;
    v7.assign(5, 100);

    // 3. 容量和大小
    cout << "v7是否为空:" << (v7.empty() ? "是" : "否") << endl;
    cout << "v7容量:" << v7.capacity() << " 大小:" << v7.size() << endl;
    v7.resize(3);
    cout << "v7 resize(3)后:容量=" << v7.capacity() << " 大小=" << v7.size() << endl;
    v7.resize(8, 9);
    cout << "v7 resize(8,9)后:容量=" << v7.capacity() << " 大小=" << v7.size() << endl;

    // 4. 插入删除
    v7.push_back(100);
    v7.pop_back();
    v7.insert(v7.begin(), 30);
    v7.insert(v7.begin() + 1, 2, 40);
    v7.erase(v7.begin());

    // 5. 元素访问
    cout << "v7[0] = " << v7[0] << endl;
    cout << "v7.at(1) = " << v7.at(1) << endl;
    cout << "v7 front: " << v7.front() << endl;
    cout << "v7 back: " << v7.back() << endl;

    // 6. 互换和预留空间
    vector<int> v8(100000, 1);
    vector<int>(v8).swap(v8);
    cout << "v8收缩后容量:" << v8.capacity() << " 大小:" << v8.size() << endl;

    vector<int> v9;
    v9.reserve(100000);
    int num = 0;
    int* p = nullptr;
    for (int i = 0; i < 100000; i++) {
        v9.push_back(i);
        if (p != &v9[0]) {
            p = &v9[0];
            num++;
        }
    }
    cout << "v9扩容次数:" << num << endl;

    // 遍历输出v7
    cout << "v7最终元素:";
    for (auto it = v7.begin(); it != v7.end(); it++) {
        cout << *it << " ";
    }
    cout << endl;

    return 0;
}

2. string 容器:字符串处理

基础介绍

string容器是对 char 数组的封装,提供了丰富的字符串操作接口,相比原生 char 数组更安全、易用,支持字符串的拼接、查找、替换、比较等核心操作。

核心功能实现

(1)构造函数
#include <iostream>
#include <string>
using namespace std;

// 构造函数演示
void testStringConstruct() {
    // 空构造
    string s1;
    // 字符串构造
    string s2("hello world");
    // 拷贝构造
    string s3(s2);
    // n个字符构造
    string s4(5, 'a'); // 5个'a'
}
(2)赋值操作
// 赋值操作演示
void testStringAssign() {
    string s1;
    // operator=赋值
    s1 = "hello";
    string s2;
    s2 = s1;
    string s3;
    s3 = 'a';
    // assign赋值
    string s4;
    s4.assign("hello world");
    string s5;
    s5.assign("hello world", 5); // 取前5个字符
    string s6;
    s6.assign(s5);
    string s7;
    s7.assign(5, 'b'); // 5个'b'
}
(3)末尾拼接
// 末尾拼接演示
void testStringAppend() {
    string s1 = "hello";
    // operator+=拼接
    s1 += " world";
    s1 += '!';
    string s2 = " my friend";
    s1 += s2;
    // append拼接
    string s3 = "hello";
    s3.append(" world");
    s3.append("!!!", 2); // 拼接前2个字符
    s3.append(s2, 3, 5); // 从s2的第3位开始取5个字符拼接
}
(4)查找与替换
// 查找与替换演示
void testStringFindReplace() {
    string s = "hello world hello c++";
    // find查找(从左到右)
    int pos1 = s.find("hello"); // 找到返回起始索引,没找到返回-1
    // rfind查找(从右到左)
    int pos2 = s.rfind("hello");
    // replace替换
    s.replace(pos1, 5, "HELLO"); // 从pos1开始,替换5个字符为"HELLO"
}
(5)字符串比较
// 字符串比较演示
void testStringCompare() {
    string s1 = "hello";
    string s2 = "world";
    // compare比较(按ASCII码比较,相等返回0,s1>s2返回1,s1<s2返回-1)
    int ret = s1.compare(s2);
    if (ret == 0) {
        cout << "s1 == s2" << endl;
    } else if (ret > 0) {
        cout << "s1 > s2" << endl;
    } else {
        cout << "s1 < s2" << endl;
    }
}
(6)字符存取
// 字符存取演示
void testStringAccess() {
    string s = "hello";
    // []存取
    cout << s[0] << endl;
    // at存取
    cout << s.at(1) << endl;
    // 修改字符
    s[0] = 'H';
    s.at(1) = 'E';
}
(7)插入与删除
// 插入与删除演示
void testStringInsertErase() {
    string s = "hello";
    // 插入
    s.insert(5, " world"); // 第5位插入" world"
    // 删除
    s.erase(5, 6); // 从第5位开始删除6个字符
}
(8)子串截取
// 子串截取演示
void testStringSubstr() {
    string s = "hello world";
    // 从第6位开始截取,默认到末尾
    string sub = s.substr(6);
    // 从第0位开始截取5个字符
    string sub2 = s.substr(0, 5);
    cout << "sub: " << sub << endl;
    cout << "sub2: " << sub2 << endl;
}
string 综合测试代码
#include <iostream>
#include <string>
using namespace std;

int main() {
    // 1. 构造
    string s1;
    string s2("hello world");
    string s3(s2);
    string s4(5, 'a');
    cout << "s2: " << s2 << " s3: " << s3 << " s4: " << s4 << endl;

    // 2. 赋值
    string s5;
    s5 = "hello";
    string s6 = s5;
    string s7 = 'a';
    string s8;
    s8.assign("hello world", 5);
    cout << "s5: " << s5 << " s6: " << s6 << " s7: " << s7 << " s8: " << s8 << endl;

    // 3. 拼接
    s5 += " world";
    s5 += '!';
    s8.append("!!!", 2);
    cout << "拼接后s5: " << s5 << " s8: " << s8 << endl;

    // 4. 查找替换
    string s9 = "hello world hello c++";
    int pos1 = s9.find("hello");
    int pos2 = s9.rfind("hello");
    cout << "find(hello)位置:" << pos1 << " rfind(hello)位置:" << pos2 << endl;
    s9.replace(pos1, 5, "HELLO");
    cout << "替换后s9: " << s9 << endl;

    // 5. 比较
    string s10 = "hello";
    string s11 = "world";
    int ret = s10.compare(s11);
    cout << "s10 compare s11: " << ret << endl;

    // 6. 存取
    s10[0] = 'H';
    s10.at(1) = 'E';
    cout << "修改后s10: " << s10 << endl;

    // 7. 插入删除
    string s12 = "hello";
    s12.insert(5, " world");
    cout << "插入后s12: " << s12 << endl;
    s12.erase(5, 6);
    cout << "删除后s12: " << s12 << endl;

    // 8. 子串截取
    string s13 = "hello world";
    string sub1 = s13.substr(6);
    string sub2 = s13.substr(0, 5);
    cout << "sub1: " << sub1 << " sub2: " << sub2 << endl;

    return 0;
}

3. deque 容器:双端队列

基础介绍

deque(双端队列)是一种分段连续的线性容器,支持首尾两端的快速插入 / 删除(O (1)),也支持随机访问(O (1))。相比 vector,deque 首尾操作更高效,扩容时无需复制全部元素,缺点是中间插入 / 删除效率低。

核心功能实现

(1)构造与赋值
#include <iostream>
#include <deque>
using namespace std;

// 构造与赋值演示
void testDequeConstructAssign() {
    // 构造
    deque<int> d1; // 空构造
    deque<int> d2(5, 10); // 5个10
    deque<int> d3(d2.begin(), d2.end()); // 区间构造
    deque<int> d4(d3); // 拷贝构造

    // 赋值
    deque<int> d5;
    d5 = d4; // operator=
    deque<int> d6;
    d6.assign(d5.begin(), d5.end()); // 区间赋值
    deque<int> d7;
    d7.assign(5, 100); // n个值赋值
}
(2)大小操作
// 大小操作演示
void testDequeSize() {
    deque<int> d(5, 10);
    // 判断是否为空
    if (d.empty()) {
        cout << "deque为空" << endl;
    } else {
        cout << "deque大小:" << d.size() << endl;
    }
    // 重新指定大小
    d.resize(3);
    cout << "resize(3)后大小:" << d.size() << endl;
    d.resize(8, 9);
    cout << "resize(8,9)后大小:" << d.size() << endl;
}
(3)插入与删除
// 插入与删除演示
void testDequeInsertErase() {
    deque<int> d;
    // 尾插
    d.push_back(10);
    // 头插
    d.push_front(20);
    // 尾删
    d.pop_back();
    // 头删
    d.pop_front();
    // 插入
    d.insert(d.begin(), 30); // 头部插入30
    d.insert(d.begin() + 1, 2, 40); // 第二个位置插入2个40
    // 删除
    d.erase(d.begin()); // 删除头部
    // 清空
    d.clear();
}
(4)数据存取
// 数据存取演示
void testDequeAccess() {
    deque<int> d(5, 10);
    // []访问
    cout << d[0] << endl;
    // at访问
    cout << d.at(1) << endl;
    // 头部元素
    cout << d.front() << endl;
    // 尾部元素
    cout << d.back() << endl;
}
deque 综合测试代码
#include <iostream>
#include <deque>
using namespace std;

int main() {
    // 1. 构造与赋值
    deque<int> d1;
    deque<int> d2(5, 10);
    deque<int> d3(d2.begin(), d2.end());
    deque<int> d4(d3);
    deque<int> d5 = d4;
    deque<int> d6;
    d6.assign(d5.begin(), d5.end());
    deque<int> d7(5, 100);

    // 2. 大小操作
    cout << "d7是否为空:" << (d7.empty() ? "是" : "否") << endl;
    cout << "d7大小:" << d7.size() << endl;
    d7.resize(3);
    cout << "d7 resize(3)后大小:" << d7.size() << endl;
    d7.resize(8, 9);
    cout << "d7 resize(8,9)后大小:" << d7.size() << endl;

    // 3. 插入删除
    d7.push_back(100);
    d7.push_front(200);
    cout << "push后d7 front: " << d7.front() << " back: " << d7.back() << endl;
    d7.pop_back();
    d7.pop_front();
    d7.insert(d7.begin(), 30);
    d7.insert(d7.begin() + 1, 2, 40);
    d7.erase(d7.begin());

    // 4. 数据存取
    cout << "d7[0] = " << d7[0] << endl;
    cout << "d7.at(1) = " << d7.at(1) << endl;
    cout << "d7 front: " << d7.front() << " back: " << d7.back() << endl;

    // 遍历输出
    cout << "d7最终元素:";
    for (auto it = d7.begin(); it != d7.end(); it++) {
        cout << *it << " ";
    }
    cout << endl;

    return 0;
}

4. stack 容器:栈(先进后出)

基础介绍

stack(栈)是一种适配器容器,底层默认基于 deque 实现,遵循先进后出(LIFO) 原则,仅支持对栈顶元素的操作(插入、删除、访问),不支持遍历。

核心功能实现

(1)构造与基础操作
#include <iostream>
#include <stack>
using namespace std;

// stack核心操作演示
void testStack() {
    // 构造
    stack<int> s1;
    stack<int> s2(s1); // 拷贝构造

    // 入栈
    s1.push(10);
    s1.push(20);
    s1.push(30);

    // 访问栈顶
    cout << "栈顶元素:" << s1.top() << endl;

    // 出栈
    s1.pop();
    cout << "出栈后栈顶:" << s1.top() << endl;

    // 大小与判空
    cout << "栈的大小:" << s1.size() << endl;
    cout << "栈是否为空:" << (s1.empty() ? "是" : "否") << endl;
}
stack 综合测试代码
#include <iostream>
#include <stack>
using namespace std;

int main() {
    // 构造
    stack<int> s;

    // 入栈
    s.push(10);
    s.push(20);
    s.push(30);
    s.push(40);

    // 栈的大小
    cout << "栈的大小:" << s.size() << endl;

    // 访问并出栈(遍历栈)
    cout << "栈元素(从顶到底):";
    while (!s.empty()) {
        // 访问栈顶
        cout << s.top() << " ";
        // 出栈
        s.pop();
    }
    cout << endl;

    // 判空
    cout << "出栈后栈是否为空:" << (s.empty() ? "是" : "否") << endl;

    return 0;
}

5. queue 容器:队列(先进先出)

基础介绍

queue(队列)是适配器容器,底层默认基于 deque 实现,遵循先进先出(FIFO) 原则,支持队尾插入、队头删除,可访问队头 / 队尾元素,不支持遍历。

核心功能实现

(1)构造与基础操作
#include <iostream>
#include <queue>
using namespace std;

// queue核心操作演示
void testQueue() {
    // 构造
    queue<int> q1;
    queue<int> q2(q1); // 拷贝构造

    // 入队
    q1.push(10);
    q1.push(20);
    q1.push(30);

    // 访问队头/队尾
    cout << "队头:" << q1.front() << " 队尾:" << q1.back() << endl;

    // 出队
    q1.pop();
    cout << "出队后队头:" << q1.front() << endl;

    // 大小与判空
    cout << "队列大小:" << q1.size() << endl;
    cout << "队列是否为空:" << (q1.empty() ? "是" : "否") << endl;
}
queue 综合测试代码
#include <iostream>
#include <queue>
using namespace std;

int main() {
    // 构造
    queue<int> q;

    // 入队
    q.push(10);
    q.push(20);
    q.push(30);
    q.push(40);

    // 队列大小
    cout << "队列大小:" << q.size() << endl;

    // 访问并出队(遍历队列)
    cout << "队列元素(先进先出):";
    while (!q.empty()) {
        // 访问队头
        cout << q.front() << " ";
        // 出队
        q.pop();
    }
    cout << endl;

    // 判空
    cout << "出队后队列是否为空:" << (q.empty() ? "是" : "否") << endl;

    return 0;
}

6. list 容器:双向链表

基础介绍

list是双向链表容器,内存空间不连续,支持任意位置的高效插入 / 删除(O (1)),但不支持随机访问(只能迭代器遍历)。提供反转、排序等特有功能。

核心功能实现

(1)构造、赋值与交换
#include <iostream>
#include <list>
using namespace std;

// 构造、赋值、交换演示
void testListConstructAssignSwap() {
    // 构造
    list<int> l1; // 空构造
    list<int> l2(5, 10); // 5个10
    list<int> l3(l2.begin(), l2.end()); // 区间构造
    list<int> l4(l3); // 拷贝构造

    // 赋值
    list<int> l5;
    l5 = l4; // operator=
    list<int> l6;
    l6.assign(l5.begin(), l5.end()); // 区间赋值
    list<int> l7;
    l7.assign(5, 100); // n个值赋值

    // 交换
    l2.swap(l7);
}
(2)大小操作
// 大小操作演示
void testListSize() {
    list<int> l(5, 10);
    // 判空
    if (l.empty()) {
        cout << "list为空" << endl;
    } else {
        cout << "list大小:" << l.size() << endl;
    }
    // 重新指定大小
    l.resize(3);
    cout << "resize(3)后大小:" << l.size() << endl;
    l.resize(8, 9);
    cout << "resize(8,9)后大小:" << l.size() << endl;
}
(3)插入与删除
// 插入与删除演示
void testListInsertErase() {
    list<int> l;
    // 尾插
    l.push_back(10);
    // 头插
    l.push_front(20);
    // 尾删
    l.pop_back();
    // 头删
    l.pop_front();
    // 插入
    l.insert(l.begin(), 30); // 头部插入30
    l.insert(l.begin()++, 2, 40); // 插入2个40
    // 删除
    l.erase(l.begin()); // 删除头部
    // 移除指定值
    l.remove(40); // 删除所有值为40的元素
    // 清空
    l.clear();
}
(4)数据存取、反转与排序
// 存取、反转、排序演示
void testListAccessSort() {
    list<int> l = {3,1,4,2,5};
    // 存取(仅支持front/back)
    cout << "front: " << l.front() << " back: " << l.back() << endl;
    // 反转
    l.reverse();
    // 排序
    l.sort(); // 默认升序
    l.sort(greater<int>()); // 降序
}
list 综合测试代码
#include <iostream>
#include <list>
#include <algorithm> // greater
using namespace std;

int main() {
    // 1. 构造与赋值
    list<int> l1;
    list<int> l2(5, 10);
    list<int> l3(l2.begin(), l2.end());
    list<int> l4 = l3;
    list<int> l5;
    l5.assign(5, 100);

    // 2. 大小操作
    cout << "l5是否为空:" << (l5.empty() ? "是" : "否") << endl;
    cout << "l5大小:" << l5.size() << endl;
    l5.resize(3);
    cout << "l5 resize(3)后大小:" << l5.size() << endl;

    // 3. 插入删除
    l5.push_back(10);
    l5.push_front(20);
    cout << "push后l5 front: " << l5.front() << " back: " << l5.back() << endl;
    l5.pop_back();
    l5.pop_front();
    l5.insert(l5.begin(), 30);
    l5.insert(++l5.begin(), 2, 40);
    l5.erase(l5.begin());
    l5.remove(40); // 删除所有40

    // 4. 反转与排序
    list<int> l6 = {3,1,4,2,5};
    cout << "排序前l6:";
    for (auto it = l6.begin(); it != l6.end(); it++) {
        cout << *it << " ";
    }
    cout << endl;
    l6.reverse(); // 反转
    cout << "反转后l6:";
    for (auto it = l6.begin(); it != l6.end(); it++) {
        cout << *it << " ";
    }
    cout << endl;
    l6.sort(); // 升序
    cout << "升序排序后l6:";
    for (auto it = l6.begin(); it != l6.end(); it++) {
        cout << *it << " ";
    }
    cout << endl;
    l6.sort(greater<int>()); // 降序
    cout << "降序排序后l6:";
    for (auto it = l6.begin(); it != l6.end(); it++) {
        cout << *it << " ";
    }
    cout << endl;

    // 5. 交换
    l2.swap(l5);
    cout << "交换后l2大小:" << l2.size() << " l5大小:" << l5.size() << endl;

    return 0;
}

7. set 容器:有序不重复集合

基础介绍

set底层基于红黑树实现,元素有序且唯一,插入时自动排序,不可直接修改元素(需删除后重新插入)。multiset是 set 的变体,支持重复元素。

核心功能实现

(1)构造、赋值与大小交换
#include <iostream>
#include <set>
using namespace std;

// 构造、赋值、大小交换演示
void testSetConstructAssign() {
    // 构造
    set<int> s1; // 空构造
    set<int> s2(s1); // 拷贝构造

    // 赋值
    set<int> s3;
    s3 = s2;

    // 插入(自动排序+去重)
    s1.insert(3);
    s1.insert(1);
    s1.insert(2);
    s1.insert(2); // 重复元素,插入失败

    // 大小与交换
    cout << "s1大小:" << s1.size() << endl;
    s2.swap(s1);
    cout << "交换后s2大小:" << s2.size() << endl;
}
(2)插入删除、查找统计
// 插入删除、查找统计演示
void testSetInsertFind() {
    set<int> s;
    // 插入
    s.insert(10);
    s.insert(20);
    s.insert(30);
    // 删除
    s.erase(s.begin()); // 删除第一个元素
    s.erase(20); // 删除值为20的元素
    // 查找
    set<int>::iterator it = s.find(30);
    if (it != s.end()) {
        cout << "找到元素:" << *it << endl;
    }
    // 统计(set中count只能是0或1)
    int num = s.count(30);
    cout << "30的个数:" << num << endl;

    // multiset演示
    multiset<int> ms;
    ms.insert(10);
    ms.insert(10);
    cout << "multiset中10的个数:" << ms.count(10) << endl;
}
(3)set 排序(自定义类型)
// 自定义类型排序
class Person {
public:
    Person(string name, int age) : m_Name(name), m_Age(age) {}
    string m_Name;
    int m_Age;
};

// 排序规则(仿函数)
class ComparePerson {
public:
    bool operator()(const Person& p1, const Person& p2) {
        // 按年龄降序
        return p1.m_Age > p2.m_Age;
    }
};

void testSetSort() {
    set<Person, ComparePerson> s;
    // 插入自定义对象
    s.insert(Person("张三", 20));
    s.insert(Person("李四", 30));
    s.insert(Person("王五", 25));
    // 遍历
    for (auto it = s.begin(); it != s.end(); it++) {
        cout << "姓名:" << it->m_Name << " 年龄:" << it->m_Age << endl;
    }
}
set 综合测试代码
#include <iostream>
#include <set>
#include <string>
using namespace std;

// 自定义类型排序示例
class Person {
public:
    Person(string name, int age) : m_Name(name), m_Age(age) {}
    string m_Name;
    int m_Age;
};

class ComparePerson {
public:
    bool operator()(const Person& p1, const Person& p2) {
        return p1.m_Age > p2.m_Age; // 按年龄降序
    }
};

int main() {
    // 1. 基础set操作
    set<int> s;
    // 插入(自动排序、去重)
    s.insert(3);
    s.insert(1);
    s.insert(2);
    s.insert(2);
    cout << "set大小:" << s.size() << endl;
    cout << "set元素(升序):";
    for (auto it = s.begin(); it != s.end(); it++) {
        cout << *it << " ";
    }
    cout << endl;

    // 查找
    auto it = s.find(2);
    if (it != s.end()) {
        cout << "找到元素:" << *it << endl;
    }
    // 统计
    cout << "元素2的个数:" << s.count(2) << endl;

    // 删除
    s.erase(1);
    cout << "删除1后set元素:";
    for (auto it = s.begin(); it != s.end(); it++) {
        cout << *it << " ";
    }
    cout << endl;

    // 2. multiset操作
    multiset<int> ms;
    ms.insert(10);
    ms.insert(10);
    ms.insert(20);
    cout << "multiset中10的个数:" << ms.count(10) << endl;
    cout << "multiset元素:";
    for (auto it = ms.begin(); it != ms.end(); it++) {
        cout << *it << " ";
    }
    cout << endl;

    // 3. 自定义类型排序
    set<Person, ComparePerson> s_person;
    s_person.insert(Person("张三", 20));
    s_person.insert(Person("李四", 30));
    s_person.insert(Person("王五", 25));
    cout << "自定义类型set(按年龄降序):" << endl;
    for (auto it = s_person.begin(); it != s_person.end(); it++) {
        cout << "姓名:" << it->m_Name << " 年龄:" << it->m_Age << endl;
    }

    // 4. 交换
    set<int> s1{5,4,3};
    set<int> s2{1,2};
    s1.swap(s2);
    cout << "交换后s1:";
    for (auto it = s1.begin(); it != s1.end(); it++) {
        cout << *it << " ";
    }
    cout << endl;

    return 0;
}

8. map 容器:键值对集合

基础介绍

map底层基于红黑树实现,存储键值对(key-value),key 唯一且自动排序,可通过 key 快速查找 value(O (logn)),不可直接修改 key,可修改 value。

核心功能实现

(1)构造、赋值与大小交换
#include <iostream>
#include <map>
#include <string>
using namespace std;

// 构造、赋值、大小交换演示
void testMapConstructAssign() {
    // 构造
    map<int, string> m1; // 空构造
    map<int, string> m2(m1); // 拷贝构造

    // 赋值
    map<int, string> m3;
    m3 = m2;

    // 插入
    m1.insert(pair<int, string>(1, "张三"));
    m1.insert(make_pair(2, "李四"));
    m1.insert(map<int, string>::value_type(3, "王五"));
    m1[4] = "赵六"; // 重载[],不存在则插入

    // 大小与交换
    cout << "m1大小:" << m1.size() << endl;
    m2.swap(m1);
    cout << "交换后m2大小:" << m2.size() << endl;
}
(2)插入删除、查找统计
// 插入删除、查找统计演示
void testMapInsertFind() {
    map<int, string> m;
    // 插入
    m.insert(pair<int, string>(1, "张三"));
    // 删除
    m.erase(m.begin()); // 删除第一个元素
    m.erase(1); // 删除key为1的元素
    // 查找
    map<int, string>::iterator it = m.find(2);
    if (it != m.end()) {
        cout << "找到key=2,value=" << it->second << endl;
    }
    // 统计(map中count只能是0或1)
    int num = m.count(2);
    cout << "key=2的个数:" << num << endl;
}
(3)map 排序
// map排序(按key降序)
class CompareMap {
public:
    bool operator()(int k1, int k2) {
        return k1 > k2; // key降序
    }
};

void testMapSort() {
    map<int, string, CompareMap> m;
    m.insert(make_pair(1, "张三"));
    m.insert(make_pair(2, "李四"));
    m.insert(make_pair(3, "王五"));
    // 遍历
    for (auto it = m.begin(); it != m.end(); it++) {
        cout << "key=" << it->first << " value=" << it->second << endl;
    }
}
map 综合测试代码
#include <iostream>
#include <map>
#include <string>
using namespace std;

// 自定义排序规则(key降序)
class CompareMap {
public:
    bool operator()(int k1, int k2) {
        return k1 > k2;
    }
};

int main() {
    // 1. 基础map操作
    map<int, string> m;
    // 四种插入方式
    m.insert(pair<int, string>(1, "张三"));
    m.insert(make_pair(2, "李四"));
    m.insert(map<int, string>::value_type(3, "王五"));
    m[4] = "赵六";

    cout << "map大小:" << m.size() << endl;
    cout << "map元素(key升序):" << endl;
    for (auto it = m.begin(); it != m.end(); it++) {
        cout << "key=" << it->first << " value=" << it->second << endl;
    }

    // 查找
    auto it = m.find(2);
    if (it != m.end()) {
        cout << "找到key=2,value=" << it->second << endl;
    }

    // 统计
    cout << "key=2的个数:" << m.count(2) << endl;

    // 修改value
    m[2] = "李四-修改后";
    cout << "修改后key=2的value:" << m[2] << endl;

    // 删除
    m.erase(4);
    cout << "删除key=4后map元素:" << endl;
    for (auto it = m.begin(); it != m.end(); it++) {
        cout << "key=" << it->first << " value=" << it->second << endl;
    }

    // 2. 自定义排序(key降序)
    map<int, string, CompareMap> m_sort;
    m_sort.insert(make_pair(1, "张三"));
    m_sort.insert(make_pair(2, "李四"));
    m_sort.insert(make_pair(3, "王五"));
    cout << "map(key降序):" << endl;
    for (auto it = m_sort.begin(); it != m_sort.end(); it++) {
        cout << "key=" << it->first << " value=" << it->second << endl;
    }

    // 3. 交换
    map<int, string> m1{{5,"A"},{6,"B"}};
    map<int, string> m2{{7,"C"},{8,"D"}};
    m1.swap(m2);
    cout << "交换后m1:" << endl;
    for (auto it = m1.begin(); it != m1.end(); it++) {
        cout << "key=" << it->first << " value=" << it->second << endl;
    }

    return 0;
}

总结

  • vector:适合随机访问、尾部操作频繁的场景;
  • string:专门用于字符串处理,替代原生 char 数组;
  • deque:适合首尾插入 / 删除频繁的场景;
  • stack/queue:适配特定的先进后出 / 先进先出业务场景;
  • list:适合任意位置插入 / 删除频繁的场景;
  • set:适合有序、唯一的集合场景;
  • map:适合键值对存储、按 key 查找的场景。

开发板推荐:天空星STM32F407VET6开发板

超高性价比 STM32主控 | 超高主频 | 一板兼容百芯 | 比赛神器 | 沉金彩色丝印

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值