-
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 查找的场景。
568

被折叠的 条评论
为什么被折叠?



