This repository has been archived on 2022-06-22. You can view files and clone it, but cannot push or open issues or pull requests.
usaco-guide/content/3_Bronze/Pairs_Tuples.mdx

125 lines
4 KiB
Text
Raw Normal View History

2020-06-09 15:25:25 +00:00
---
2020-06-22 14:26:06 +00:00
id: pairs-tuples
2020-07-06 21:21:40 +00:00
title: Pairs & Tuples in C++
author: Benjamin Qi, Nathan Wang, Darren Yao, Abutalib Namazov
2020-06-22 19:59:16 +00:00
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.
2020-07-06 18:14:41 +00:00
prerequisites:
- Bronze - Introduction to Data Structures
2020-06-22 14:26:06 +00:00
---
2020-06-09 18:34:04 +00:00
2020-07-06 18:14:41 +00:00
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.
2020-06-26 18:29:20 +00:00
2020-07-06 18:14:41 +00:00
**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.
2020-07-10 21:56:07 +00:00
## [Pairs](http://www.cplusplus.com/reference/utility/pair/pair/)
2020-06-09 15:25:25 +00:00
2020-07-06 18:14:41 +00:00
- `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`.
2020-07-04 07:25:54 +00:00
- `{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)`.
2020-06-09 15:25:25 +00:00
- `pair.first`: The first value of the pair.
- `pair.second`: The second value of the pair.
2020-06-22 14:26:06 +00:00
Example:
2020-06-09 15:25:25 +00:00
```cpp
#include <iostream>
using namespace std;
int main() {
2020-07-04 07:25:54 +00:00
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
2020-06-09 15:25:25 +00:00
}
/* Output
* Testing 123
2020-07-04 07:25:54 +00:00
* Testing curly braces
* It is possible to edit pairs after declaring them 123
2020-06-09 15:25:25 +00:00
*/
```
2020-07-06 21:21:40 +00:00
## [Tuples](http://www.cplusplus.com/reference/tuple/)
2020-07-06 18:14:41 +00:00
2020-07-06 21:21:40 +00:00
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.
2020-07-06 18:14:41 +00:00
2020-07-06 21:21:40 +00:00
- `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.
2020-07-06 18:14:41 +00:00
2020-07-06 21:21:40 +00:00
Note that it is illegal to do something like the following since $z$ is not constant:
2020-07-06 18:14:41 +00:00
2020-07-06 21:21:40 +00:00
```cpp
tuple<int,int,int> t{3,4,5};
int z = 1; cout << get<z>(t);
2020-07-06 18:14:41 +00:00
```
2020-07-06 21:21:40 +00:00
- `tie(a, b, c, ..., d) = t`: Equals `a, b, c, ..., d` to the elements of the tuple $t$ accordingly.
2020-06-11 00:49:01 +00:00
2020-07-06 21:21:40 +00:00
This is not frequently used by competitive programmers, but it is good to know and can help simplify things sometimes.
2020-07-04 07:25:54 +00:00
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
*/
```
2020-06-11 00:49:01 +00:00
2020-07-06 21:21:40 +00:00
## Sorting Pairs & Tuples
<resources>
2020-07-10 21:56:07 +00:00
<resource source="CPH" title="3.2 - Comparison Operators" starred></resource>
2020-07-06 21:21:40 +00:00
</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.
2020-07-10 21:56:07 +00:00
Example from CPH:
2020-07-06 18:14:41 +00:00
```cpp
2020-07-10 21:56:07 +00:00
#include <bits/stdc++.h>
using namespace std;
2020-07-06 21:21:40 +00:00
int main() {
2020-07-10 21:56:07 +00:00
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
*/
```
2020-07-06 21:21:40 +00:00
Tuples are sorted similarly.