0%

0-18 pair

什麼是pair

還記得嗎?如果我們需要儲存二維平面上的一個點,需要同時儲存 x, y 兩個整數,但又需要進行 sort 之類會改變位置的操作,要怎麼做呢?

在前面的章節裡,有提到struct的做法,宣告一個含兩個變數 x, y 的 struct,再自定義比較函式:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#include<bits/stdc++.h>
using namespace std;
struct Point{
int x, y;
bool operator<(Point b){
if(x != b.x) return x < b.x;
else return y < b.y;
}
}p[1005];

int main(){
for(int i=0;i<10;i++){
cin >> p[i].x >> p[i].y;
}
sort(p, p+10);
}

雖然可以理解運作原理,但是,上面那一串感覺好長好麻煩喔…

pair 的出現,可以簡化這一切!

1
2
3
4
5
6
7
8
9
10
#include<bits/stdc++.h>
using namespace std;
pair<int,int> p[1005];

int main(){
for(int i=0;i<10;i++){
cin >> p[i].first >> p[i].second;
}
sort(p, p+10);
}

pair可以將兩個變數,綁在一起儲存。可以看成一種新的型態,大幅簡化了儲存兩項東西的難度。

更強的是,能儲存的東西,不只是變數。

1
2
3
pair<int, pair<int,int>> p1
pair<int, vector<int>> p2;
pair<int, vector<pair<int, vector>>> ..... // (X)

想放什麼就放!

宣告與指派

1
2
3
4
5
pair<int, int> p;
// p = 5, 4 WRONG
p = make_pair(5, 4);
p = {8, 9};
cout << p.first << " " << p.second << "\n";

以 pair<型態, 型態> 進行宣告。

要指派的話,需先將要指派過去的兩個變數做成一個 pair,有 make_pair() 以及 {} 兩種方法。

將兩個變數綁在一起後,就可以進行指派了!

pair 中的第一個元素為 first,第二個為 second。以 p.first、p.second 進行存取,因為不是函式,所以不同於 push_back() 等等也需要加 . 的東西,並不需在後面加上()。

大小比較

pair 的比較原則是:先比前面,一樣的話再比後面。當然,pair<int, int> 是不能跟 pair<string, int> 比較的。只有相同的型態才能進行比較。

這個性質可以幫助我們省下一些時間,例如之前的例題。這題要求我們先照 x 座標,再照 y 座標排序,神奇的事發生了!這剛好就是 pair 的比較方法,因此,不用自訂比較函式,使用 pair<int, int> 儲存資料後直接 sort 就可以了!

如果今天是麻煩的比較,就自訂 pair 的比較規則吧!

1
2
3
4
bool operator <(pair<int, int> a, pair<int, int> b){
if(a.first != b.first) return a.first < b.first;
else return a.second > b.second;
}

與 vector 的連用

1
2
3
4
5
6
7
8
vector<pair<int, int>> vp;
vp.push_back(make_pair(1,2));
vp.push_back({1,2});
vp.emplace_back(1,2);
for(pair<int, int> i: vp){
//cout << i << "\n";
cout << i.first << " " << i.second << '\n';
}

要注意的點大概是這些:

  1. push_back() 裡面要放 pair,因此要記得 make_pair() 或 {} 。
  2. emplace_back() 不需要 make_pair(),直接 emplace_back(a,b) 就可以了。
  3. pair 無法直接輸出,需分開輸出 first 以及 second。

練習

ZJ a915

AC Code

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#include<bits/stdc++.h>
using namespace std;

pair<int,int> arr[1005];
int n;

int main(){
cin >> n;
for(int i=1;i<=n;i++){
cin >> arr[i].first >> arr[i].second;
}
sort(arr+1, arr+1+n);
for(int i=1;i<=n;i++){
cout << arr[i].first << " " << arr[i].second << '\n';
}
}