125 lines
No EOL
4 KiB
Text
125 lines
No EOL
4 KiB
Text
---
|
|
id: pairs-tuples
|
|
title: Pairs & Tuples in C++
|
|
author: Benjamin Qi, Nathan Wang, Darren Yao, Abutalib Namazov
|
|
description: Introduces pairs, which allow you to store two objects (possibly of different types) as a single unit, as well as tuples, which are a generalization of pairs.
|
|
prerequisites:
|
|
- Bronze - Introduction to Data Structures
|
|
---
|
|
|
|
Storing multiple elements as a single unit allows you to change the order of the elements (e.g. sorting) without mixing one component with another.
|
|
|
|
**Example:** Given some points on a plane where the $i$-th point has coordinates $(x_i,y_i)$, sort these points in increasing order of $x$ coordinate and increasing order of $y$ in case there is a tie.
|
|
|
|
If you sort one of $x_i$ and $y_i$ without considering the other, the points will not be in the correct order. We need to consider the pair $(x_i,y_i)$ as a single unit.
|
|
|
|
## [Pairs](http://www.cplusplus.com/reference/utility/pair/pair/)
|
|
|
|
- `pair<type1, type2> p`: Creates a pair `p` with two elements with the first one being of `type1` and the second one being of `type2`.
|
|
- `make_pair(a, b)`: Returns a pair with values `a`, `b`.
|
|
- `{a, b}`: With C++11 and above, this can be used as to create a pair, which is easier to write than `make_pair(a, b)`.
|
|
- `pair.first`: The first value of the pair.
|
|
- `pair.second`: The second value of the pair.
|
|
|
|
Example:
|
|
|
|
```cpp
|
|
#include <iostream>
|
|
|
|
using namespace std;
|
|
|
|
int main() {
|
|
pair<string, int> myPair1 = make_pair("Testing", 123);
|
|
cout << myPair1.first << " " << myPair1.second << endl; // Testing 123
|
|
myPair1.first = "It is possible to edit pairs after declaring them";
|
|
cout << myPair1.first << " " << myPair1.second << endl;
|
|
|
|
pair<string, string> myPair2 = {"Testing", "curly braces"};
|
|
cout << myPair2.first << " " << myPair2.second << endl; // Testing curly braces
|
|
}
|
|
|
|
/* Output
|
|
* Testing 123
|
|
* Testing curly braces
|
|
* It is possible to edit pairs after declaring them 123
|
|
*/
|
|
```
|
|
|
|
## [Tuples](http://www.cplusplus.com/reference/tuple/)
|
|
|
|
Of course, we can hold more than two values with something like `pair<int,pair<int,int>>`, but it gets messy when you need a lot of elements. In this case, using **tuples** might be more convenient.
|
|
|
|
- `tuple<type1, type2, ..., typeN> t`: Creates a tuple with `N` elements, i'th one being of `typei`.
|
|
- `make_tuple(a, b, c, ..., d)`: Returns a tuple with values written in the brackets.
|
|
- `get<i>(t)`: Returns the $i$'th element of the tuple `t`. Only works for constant $i$. Can be used to change the element of a tuple.
|
|
|
|
Note that it is illegal to do something like the following since $z$ is not constant:
|
|
|
|
```cpp
|
|
tuple<int,int,int> t{3,4,5};
|
|
int z = 1; cout << get<z>(t);
|
|
```
|
|
|
|
- `tie(a, b, c, ..., d) = t`: Equals `a, b, c, ..., d` to the elements of the tuple $t$ accordingly.
|
|
|
|
This is not frequently used by competitive programmers, but it is good to know and can help simplify things sometimes.
|
|
|
|
Example:
|
|
|
|
```cpp
|
|
#include <iostream>
|
|
#include <tuple> /// needs additional library
|
|
#include <string>
|
|
|
|
using namespace std;
|
|
|
|
int main() {
|
|
int a = 3, b = 4, c = 5;
|
|
tuple<int, int, int> t = tie(a, b, c);
|
|
cout << get<0>(t) << " " << get<1>(t) << " " << get<2>(t) << endl;
|
|
get<0>(t) = 7;
|
|
cout << get<0>(t) << " " << get<1>(t) << " " << get<2>(t) << endl;
|
|
|
|
tuple<string, string, int> tp2 = make_tuple("Hello", "world", 100);
|
|
string s1, s2; int x;
|
|
tie(s1, s2, x) = tp2;
|
|
cout << s1 << " " << s2 << " " << x << endl;
|
|
}
|
|
/* Output
|
|
* 3 4 5
|
|
* 7 4 5
|
|
* Hello world 100
|
|
*/
|
|
```
|
|
|
|
## Sorting Pairs & Tuples
|
|
|
|
<resources>
|
|
<resource source="CPH" title="3.2 - Comparison Operators" starred></resource>
|
|
</resources>
|
|
|
|
By default, C++ pairs are sorted by first element and then second element in case of a tie, which is precisely what we need for the example above.
|
|
|
|
Example from CPH:
|
|
|
|
```cpp
|
|
#include <bits/stdc++.h>
|
|
using namespace std;
|
|
|
|
int main() {
|
|
vector<pair<int,int>> v;
|
|
v.push_back({1,5});
|
|
v.push_back({2,3});
|
|
v.push_back({1,2});
|
|
sort(v.begin(), v.end());
|
|
for (pair<int,int> p: v) cout << p.first << " " << p.second << "\n";
|
|
}
|
|
|
|
/* Output:
|
|
1 2
|
|
1 5
|
|
2 3
|
|
*/
|
|
```
|
|
|
|
Tuples are sorted similarly. |