文章目录
- pair
- 一、 基本概念
- 二、pair 的声明与初始化
- 三、成员访问与修改
- 四、常用操作
- 1. 比较运算
- 2. 交换值
- 3. tie 函数(解包 pair)
- 五、pair 的应用场景
- 六、pair 与结构体 / 类的对比
- 七、pair 与 tuple 的对比
- 八、代码示例
- 1. 返回多个值
- 2. 存储键值对
- 九、总结
- map
- 一、基本概念
- 二、map 的声明与初始化
- 三、常用操作
- 四、map 的应用场景
- 五、注意事项
在 C++ 编程里,map
和 pair
是标准库中十分实用的工具,能让我们高效地处理数据。下面这个简单的代码示例就展示了它们是如何配合使用的:
#include
#include
#include
int main() {
std::map<int, std::string> studentMap;
// 使用 std::pair 显式构造插入
studentMap.insert(std::pair<int, std::string>(1, "Alice"));
// 使用花括号隐式构造插入
studentMap.insert({2, "Bob"});
// 遍历 map 并输出键值对
for (const auto& entry : studentMap) {
std::cout << "学号: " << entry.first << ", 姓名: " << entry.second << std::endl;
}
return 0;
}
在这段代码中,我们创建了一个 map
,它的键是 int
类型(代表学号),值是 string
类型(代表姓名)。接着,我们使用 pair
来创建键值对并插入到 map
中。最后,通过遍历 map
输出存储的信息。从这个示例中可以看出,pair
为 map
提供了一种方便的方式来组织和存储键值对。接下来,让我们深入探讨 map
和 pair
的详细特性、使用方法以及它们之间的关系。
pair 是 C++ 标准库中的一个模板类,用于将两个不同类型的值组合成一个单元。它提供了一种简单的方式来存储和传递多个相关数据,而无需定义复杂的结构体或类。
#include // 包含pair的头文件
// 方式1:显式指定类型并初始化
std::pair<int, std::string> student(1001, "Alice");
// 方式2:使用自动类型推导(C++11+)
auto student = std::make_pair(1001, "Alice");
// 方式3:直接初始化
std::pair student(1001, "Alice"); // C++14+
pair 有两个公共成员变量:first
和 second
。
// 访问成员
int id = student.first; // 1001
std::string name = student.second; // "Alice"
// 修改成员
student.second = "Bob"; // 现在second为"Bob"
pair 支持按字典序比较:
std::pair<int, int> a(1, 2);
std::pair<int, int> b(1, 3);
std::cout << (a < b); // 输出1(因为a.second < b.second)
std::swap(a, b); // 交换a和b的值
auto [id, name] = student; // C++17结构化绑定
std::cout << id << " " << name; // 输出1001 Bob
通常在算法竞赛或者编程中,大家习惯用
#define PII pair
来简化代码,提高代码的可维护性:#include
#include #include // 定义宏 PII 为 pair #define PII pair<int, int> int main() { // 使用 PII 来声明变量 PII point(1, 2); std::cout << "第一个元素: " << point.first << std::endl; std::cout << "第二个元素: " << point.second << std::endl; // 在队列中使用 PII std::queue<PII> q; q.push({3, 4}); PII front = q.front(); std::cout << "队列队头元素的第一个值: " << front.first << std::endl; std::cout << "队列队头元素的第二个值: " << front.second << std::endl; return 0; } 在上述代码中,
#define PII pair
定义了一个宏PII
,之后在代码里就可以使用 PII 来替代pair
进行变量声明和使用。例如PII point(1, 2);
就相当于pair
。point(1, 2);
返回多个值:
std::pair<int, double> calculate() {
return {100, 3.14};
}
存储键值对:
std::map<std::string, int> scores = {
{"Alice", 90},
{"Bob", 85}
};
临时数据组合:
std::vector<std::pair<int, char>> data = {
{1, 'A'},
{2, 'B'}
};
特性 | pair | 结构体 / 类 |
---|---|---|
定义方式 | 无需显式定义,直接使用模板 | 需要定义 struct/class |
成员访问 | 通过.first 和.second 直接访问 | 通过成员变量或 getter 方法 |
扩展性 | 固定两个元素,无法扩展 | 可灵活添加成员变量 |
适用场景 | 简单数据组合,临时使用 | 复杂数据模型,需要封装 |
特性 | pair | tuple |
---|---|---|
元素数量 | 固定两个 | 任意数量(≥0) |
类型推导 | 自动推导(make_pair) | 自动推导(make_tuple) |
访问方式 | .first 和.second | get<0>()、get<1>() 等 |
应用场景 | 简单二元组合 | 多元数据组合 |
#include
#include
std::pair<int, double> get_data() {
return std::make_pair(100, 3.14);
}
int main() {
auto [id, value] = get_data();
std::cout << "ID: " << id << ", Value: " << value << std::endl;
return 0;
}
// 输出:ID: 100, Value: 3.14
#include
#include
int main() {
std::map<int, std::string> students = {
{1001, "Alice"},
{1002, "Bob"}
};
for (const auto& [id, name] : students) {
std::cout << id << " -> " << name << std::endl;
}
return 0;
}
// 输出:
// 1001 -> Alice
// 1002 -> Bob
map 是 C++ 标准模板库(STL)中的一个关联容器,用于存储键值对(key-value pairs),并支持高效的查找、插入和删除操作。其核心特性如下:
• 有序性:默认按键(key)的升序排列(底层基于红黑树实现)。
• 唯一性:每个键只能出现一次,不允许重复。
• 快速访问:查找、插入、删除的平均时间复杂度为 O(log n)。
#include
#include
// 声明:键为int类型,值为string类型
std::map<int, std::string> myMap;
// 初始化方式
std::map<int, std::string> scores = {
{1, "Alice"},
{2, "Bob"},
{3, "Charlie"}
};
// 方式1:使用insert()函数
myMap.insert({4, "David"});
// 方式2:直接赋值(若键不存在则插入,存在则覆盖)
myMap[5] = "Eve";
// 方式1:使用find()函数
auto it = myMap.find(3);
if (it != myMap.end()) {
std::cout << "键3对应的值:" << it->second << std::endl;
}
// 方式2:直接访问(若键不存在则自动插入默认值)
std::cout << myMap[2] << std::endl; // 输出Bob
// 删除键为5的元素
myMap.erase(5);
// 删除所有元素
myMap.clear();
// 使用迭代器遍历
for (auto& pair : myMap) {
std::cout << "键:" << pair.first << ",值:" << pair.second << std::endl;
}
<
运算符)。unordered_map
提高效率。