元组:pair 与 tuple

发布时间 2023-07-19 14:15:33作者: Only_Remember_Z

众所周知,代码简短不一定易懂,但 pair 和 tuple 也确实是十分方便的多元组,适当使用可以使代码变简短。

前置:结构体

应该是最简洁明了的多元组吧。

当你需要将一些数据捆绑在一起时, 你可以使用结构体。

struct Node {
  int a, b;
  string c;
} a;

cout << a.a << ' ' << a.b << ' ' << a.c;

结构体的排序规则需要自定义,但这也不失为它的一个优点:灵活。

struct Node {
  int a, b;
  string c;
  bool operator < (const Node &i) const {
    return (a != i.a ? a < i.a : b > i.b);
  }
} a[10];

sort(a, a + 10);

二元组:pair

定义方式

定义一个二元组:pair<第一元类型, 第二元类型> 二元组组名;

pair<int, int>
pair<string, double>
pair<vector<int>, vector<string>>
pair<pair<int, double>, pair<pair<int, int>, vector<string>>>

当然也可以……

struct Node {
  int a, b, c, x, y, z;
  string name;
  vector<int> g;
};

pair<int, Node>

基本使用

假设定义了一个 pair<int, int> a

  • 调用:第一元a.first,第二元a.second
  • 可以直接修改。
  • 支持大括号赋值:a = {10, 15}

特殊使用

排序时,可以不用自定义规则,默认按第一元从小到大,当第一元相等时第二元从小到大。

多元组:tuple

pair 仅仅只是二元组,当你要实现多元时它就显得没那么方便了(当然可以 pair 套 pair),为了方便与美观,就需要多元组:tuple。

虽然是多元组,但它比起 pair 也有些不足之处,比如说头文件方面……

定义方式

注意,需要头文件:#include <tuple>

定义一个 \(n\) 元组:tuple<第一元类型, 第二元类型, 第三元类型 ... 第 n 元类型> n 元组组名;

就不举例了。

基本使用

假设定义了一个四元组 tuple<int, string, double, long long> a

  • 调用:访问第 \(i\) 个元素:get<i>(a);\(i\)\(0\) 开始
  • 可以直接修改。
  • 不支持大括号赋值,需要:a = make_tuple(x, y, z, w)

特殊使用

同 pair。

结构化绑定

C++17 特性,方便又快捷。

安照多元组中各个元的出现顺序,将各个元素的值复制到变量上,可以直接使用变量进行操作,无需使用多元组的访问方法。

格式

假设定义了一个四元组 tuple<int, string, double, long long> a

你现在想取出 a 中的每个元素,分别存储在四个变量 xyzw 中,格式为:auto [x, y, z, w] = a;

auto [x[1], x[2], x[3] ... x[n]] = n 元组,auto 自动匹配元素类型。

#include <iostream>
#include <tuple>

using namespace std;

tuple<int, int, int, int> a;

int main () {
  ios::sync_with_stdio(0), cin.tie(0);
  cin >> get<0>(a) >> get<1>(a) >> get<2>(a) >> get<3>(a);
  auto [x, y, z, w] = a;
  cout << x + y << ' ' << z + w << ' ' << x * y * z * w;
  return 0;
}

输入 1 3 5 7,输出 4 12 105

实际应用

我比较常用的地方:

  • Dij 取出 pq.top()(例:auto [now, lv] = pq.top()),或在边权不相等时遍历其他点(例:for(auto [i, x] : g[now]))。
  • 遍历各种 STL 容器(例:map<int, int> mp; for(auto [x, y] : mp))。

反正它就是一个偷懒神器!

再次强调,这是 C++17 及以上才有的特性!

所以不要乱用。

C++11 或 C++14 都不能用!

当你确定可用时可以美观代码,虽然不一定能减少行数,但绝对是能更加清晰明了!