pair和tuple

存储多个值的容器

pair 概述

pair 是存储两个值的容器,常用于存储键值对或返回两个值。

pair 的特点

  • 存储两个不同类型的值
  • 通过 first 和 second 访问
  • 支持比较运算符(先比较first,再比较second)
  • 广泛用于 map、优先队列等

pair 基本用法


#include <utility>
using namespace std;

int main() {
    // 创建 pair
    pair p1(1, "Apple");
    pair p2 = make_pair(2, "Banana");
    pair p3 = {3, "Cherry"};  // C++11 列表初始化

    // 访问元素
    cout << p1.first << endl;   // 1
    cout << p1.second << endl;  // Apple

    // 修改元素
    p1.first = 10;
    p1.second = "Orange";

    // 比较 pair
    if (p1 < p2) {
        cout << "p1 < p2" << endl;
    }

    // pair 的排序规则:先比较 first,再比较 second
    pair a(1, 3);
    pair b(1, 2);
    pair c(2, 1);

    // 比较:a.first == b.first, a.second > b.second, 所以 a > b
    // 比较:c.first > a.first, 所以 c > a

    return 0;
}
                

pair 可视化

pair 存储两个值:

first: 10
→
second: "Hello"

pair 实用场景

1. 存储坐标


typedef pair PII;

vector points = {{1, 2}, {3, 4}, {5, 6}};

// 访问坐标
int x = points[0].first;   // 1
int y = points[0].second;  // 2

// 按坐标排序
sort(points.begin(), points.end());

// 自定义排序
sort(points.begin(), points.end(), [](PII a, PII b) {
    return a.first + a.second < b.first + b.second;
});
                

2. 返回两个值


pair divide(int a, int b) {
    int quotient = a / b;
    int remainder = a % b;
    return make_pair(quotient, remainder);
}

int main() {
    auto result = divide(10, 3);
    cout << "商: " << result.first << endl;      // 3
    cout << "余数: " << result.second << endl;    // 1
    return 0;
}
                

3. 优先队列存储元素和优先级


// 存储 (距离, 编号)
priority_queue> pq;

pq.push({10, 1});  // 距离10, 编号1
pq.push({5, 2});   // 距离5, 编号2
pq.push({8, 3});   // 距离8, 编号3

// 优先队列按照 first 排序(大顶堆)
// 取出:{10, 1}, {8, 3}, {5, 2}

while (!pq.empty()) {
    cout << pq.top().first << ", " << pq.top().second << endl;
    pq.pop();
}
                

tuple 概述

tuple 是存储任意数量、任意类型值的容器(C++11引入)。

tuple 的特点

  • 可以存储任意数量的元素
  • 元素类型可以不同
  • 编译期确定元素个数和类型
  • 比 pair 更灵活

tuple 基本用法


#include <tuple>
using namespace std;

int main() {
    // 创建 tuple
    tuple t1(1, "Apple", 3.14);
    auto t2 = make_tuple(2, "Banana", 2.71);
    tuple t3 = {3, "Cherry", 1.41};

    // 访问元素(使用 get<索引>())
    cout << get<0>(t1) << endl;   // 1
    cout << get<1>(t1) << endl;   // Apple
    cout << get<2>(t1) << endl;   // 3.14

    // 结构化绑定(C++17)
    auto [id, name, price] = t1;
    cout << id << " " << name << " " << price << endl;

    // 修改元素
    get<1>(t1) = "Orange";

    // tuple 的大小
    int size = tuple_size::value;  // 3

    // tuple 的元素类型
    tuple_element<1, decltype(t1)>::type name_type;  // string

    return 0;
}
                

tie 解包


tuple getMinMaxSum(vector& v) {
    int mn = *min_element(v.begin(), v.end());
    int mx = *max_element(v.begin(), v.end());
    int sum = accumulate(v.begin(), v.end(), 0);
    return make_tuple(mn, mx, sum);
}

int main() {
    vector v = {1, 2, 3, 4, 5};

    int mn, mx, sum;
    tie(mn, mx, sum) = getMinMaxSum(v);

    cout << "最小值: " << mn << endl;    // 1
    cout << "最大值: " << mx << endl;    // 5
    cout << "总和: " << sum << endl;     // 15

    // 忽略某些值(使用 ignore)
    int mn2;
    tie(mn2, ignore, ignore) = getMinMaxSum(v);
    cout << "最小值: " << mn2 << endl;   // 1

    return 0;
}
                

tuple 可视化

tuple 存储多个值:

1
"Apple"
3.14

pair vs tuple

特性 pair tuple
元素数量固定2个任意数量
访问方式.first, .secondget<索引>()
结构化绑定支持支持
常用场景键值对、坐标多值返回
性能相同相同

何时使用 pair?何时使用 tuple?

  • 使用 pair:只需要存储2个值时
  • 使用 tuple:需要存储3个或更多值时
  • 示例:坐标用 pair,(x,y,z)用 tuple