C++ 地图 + 配对组合!3 分钟吃透 map 和 pair 的黄金搭档

文章目录

    • pair
      • 一、 基本概念
      • 二、pair 的声明与初始化
      • 三、成员访问与修改
      • 四、常用操作
        • 1. 比较运算
        • 2. 交换值
        • 3. tie 函数(解包 pair)
      • 五、pair 的应用场景
      • 六、pair 与结构体 / 类的对比
      • 七、pair 与 tuple 的对比
      • 八、代码示例
        • 1. 返回多个值
        • 2. 存储键值对
      • 九、总结
    • map
      • 一、基本概念
      • 二、map 的声明与初始化
      • 三、常用操作
      • 四、map 的应用场景
      • 五、注意事项

在 C++ 编程里,mappair 是标准库中十分实用的工具,能让我们高效地处理数据。下面这个简单的代码示例就展示了它们是如何配合使用的:

#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 输出存储的信息。从这个示例中可以看出,pairmap 提供了一种方便的方式来组织和存储键值对。接下来,让我们深入探讨 mappair 的详细特性、使用方法以及它们之间的关系。

pair

一、 基本概念

pair 是 C++ 标准库中的一个模板类,用于将两个不同类型的值组合成一个单元。它提供了一种简单的方式来存储和传递多个相关数据,而无需定义复杂的结构体或类。

二、pair 的声明与初始化

#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 有两个公共成员变量:firstsecond

// 访问成员
int id = student.first;     // 1001
std::string name = student.second; // "Alice"

// 修改成员
student.second = "Bob"; // 现在second为"Bob"

四、常用操作

1. 比较运算

pair 支持按字典序比较:

std::pair<int, int> a(1, 2);
std::pair<int, int> b(1, 3);
std::cout << (a < b); // 输出1(因为a.second < b.second)
2. 交换值
std::swap(a, b); // 交换a和b的值
3. tie 函数(解包 pair)
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);

五、pair 的应用场景

  1. 返回多个值

    std::pair<int, double> calculate() {
        return {100, 3.14};
    }
    
  2. 存储键值对

    std::map<std::string, int> scores = {
        {"Alice", 90},
        {"Bob", 85}
    };
    
  3. 临时数据组合

    std::vector<std::pair<int, char>> data = {
        {1, 'A'},
        {2, 'B'}
    };
    

六、pair 与结构体 / 类的对比

特性 pair 结构体 / 类
定义方式 无需显式定义,直接使用模板 需要定义 struct/class
成员访问 通过.first 和.second 直接访问 通过成员变量或 getter 方法
扩展性 固定两个元素,无法扩展 可灵活添加成员变量
适用场景 简单数据组合,临时使用 复杂数据模型,需要封装

七、pair 与 tuple 的对比

特性 pair tuple
元素数量 固定两个 任意数量(≥0)
类型推导 自动推导(make_pair) 自动推导(make_tuple)
访问方式 .first 和.second get<0>()、get<1>() 等
应用场景 简单二元组合 多元数据组合

八、代码示例

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
2. 存储键值对
#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

一、基本概念

map 是 C++ 标准模板库(STL)中的一个关联容器,用于存储键值对(key-value pairs),并支持高效的查找、插入和删除操作。其核心特性如下:
• 有序性:默认按键(key)的升序排列(底层基于红黑树实现)。
• 唯一性:每个键只能出现一次,不允许重复。
• 快速访问:查找、插入、删除的平均时间复杂度为 O(log n)。

二、map 的声明与初始化

#include 
#include 

// 声明:键为int类型,值为string类型
std::map<int, std::string> myMap;

// 初始化方式
std::map<int, std::string> scores = {
    {1, "Alice"},
    {2, "Bob"},
    {3, "Charlie"}
};

三、常用操作

  1. 插入元素
// 方式1:使用insert()函数
myMap.insert({4, "David"});

// 方式2:直接赋值(若键不存在则插入,存在则覆盖)
myMap[5] = "Eve";
  1. 查找元素
// 方式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
  1. 删除元素
// 删除键为5的元素
myMap.erase(5);

// 删除所有元素
myMap.clear();
  1. 遍历元素
// 使用迭代器遍历
for (auto& pair : myMap) {
    std::cout << "键:" << pair.first << ",值:" << pair.second << std::endl;
}

四、map 的应用场景

  1. 字典查询:如单词到释义的映射。
  2. 统计频率:统计字符或数字出现的次数。
  3. 快速查找:根据唯一标识(如 ID、座位号)快速获取信息。
  4. 有序存储:需要按键排序的场景(如学生成绩排名)。

五、注意事项

  1. 键的类型:键必须是可比较的(默认使用 < 运算符)。
  2. 重复键:插入重复键会被忽略(不会报错)。
  3. 性能:若不需要有序性,优先使用 unordered_map 提高效率。

你可能感兴趣的:(STL,数据结构与算法,c++,算法,开发语言,stl)