[C++]優先順位queueコンテナのデフォルトの使い方
参考資料
http://www.cplusplus.com/reference/queue/priority_queue/
https://blockdmask.tistory.com/107
https://kbj96.tistory.com/15
https://hydroponicglass.tistory.com/169
priority queueはC++のSTLコンテナの1つであり、ヒップホップ資料構造によって内部的に実装される優先キューを使用することができる.はヘッダファイルに含まれます.
templateclass Container = vector,
class Compare = less>
class priority_queue;優先キューは、基本的にベクトルコンテナによって実現されるが、dequeueとともに使用することもできる. ソート基準は基本的に降順(less)であるが、これも基準を変更する. デフォルトジェネレータタイプ:priority queuepq; 内部コンテナ変更:priority queuepq; ソート基準の変更:優先順位queuepq;
基本的な使い方
http://www.cplusplus.com/reference/queue/priority_queue/
https://blockdmask.tistory.com/107
https://kbj96.tistory.com/15
https://hydroponicglass.tistory.com/169
priority queueはC++のSTLコンテナの1つであり、ヒップホップ資料構造によって内部的に実装される優先キューを使用することができる.
template
class Compare = less
class priority_queue;
基本的な使い方 #include <iostream>
#include <queue>
using namespace std;
int main() {
// priority_queue<int, vector<int>, less<int>> pq;
priority_queue<int> pq; // 내림차순
// 원소 삽입 (가장 큰 값이 top에 오도록)
pq.push(4);
pq.push(7);
pq.push(3);
pq.push(1);
pq.push(10);
cout << pq.size() << "\n"; // 5
while (!pq.empty()) {
cout << pq.top() << " "; // 10 7 4 3 1
pq.pop();
}
return 0;
}
最小値から昇順で出力する場合は、priority_queue<int , vector<int>, greater<int>> pq;
と宣言してもよいし、プッシュ要素から負の数に変換してもよい.優先キューのデフォルト値が最大値であるため、負の値では、スロットル値が最小の要素が昇順で出力され始めます.#include <iostream>
#include <queue>
using namespace std;
int main() {
// 오름차순
priority_queue<int, vector<int>, greater<int>> pq;
// 원소 삽입 (가장 작은 값이 top에 오도록)
pq.push(4);
pq.push(7);
pq.push(3);
pq.push(1);
pq.push(10);
cout << pq.size() << "\n"; // 5
while (!pq.empty()) {
cout << pq.top() << " "; // 1 3 4 7 10
pq.pop();
}
return 0;
}
#include <iostream>
#include <queue>
using namespace std;
int main() {
priority_queue<int> pq;
// 음수로 변환해서 원소 삽입
pq.push(-4);
pq.push(-7);
pq.push(-3);
pq.push(-1);
pq.push(-10);
cout << pq.size() << "\n"; // 5
// 절댓값이 작은 원소부터 출력되도록 (오름차순)
while (!pq.empty()) {
cout << -pq.top() << " "; // 1 3 4 7 10
pq.pop();
}
return 0;
}
白峻11286号です。お尻を折る
https://www.acmicpc.net/problem/11286 #include <iostream>
#include <queue>
using namespace std;
int main() {
cin.sync_with_stdio(0);
cin.tie(0);
int n;
cin >> n;
// pair의 first를 기준으로,
// 절댓값이 가장 작은 원소가 우선순위 큐의 top에 위치함.
// 출력할 때는 절댓값이 아닌 원래 값으로 출력
priority_queue<pair<int, int>, vector<pair<int, int>>, greater<pair<int, int>>> pq;
int x;
for (int i = 0; i < n; i++) {
cin >> x;
if (x == 0) {
if (pq.empty())
cout << "0\n";
else {
cout << pq.top().second << "\n";
pq.pop();
}
}
else {
// 절댓값이 작을수록 top에 위치하도록
pq.push({ abs(x), x });
}
}
return 0;
}
演算子を使用したソート構造の再ロード
生徒の学号を小さくしたいほど優先度Qのトップに入るにはどうすればいいのでしょうか.
優先度キューの内部はhipによって実現され、ルートノードの値が最も高い場合は最小hip、値が最も高い場合は最大hipである.
優先キューは、新しい要素が挿入されたときの親ノードとサイズを比較することで、2つのノードを交換するかどうかを決定します.親ノードのキー値が常に子ノードのキー値(最小ヒップ)より小さいか大きい場合は、交換されません.
次の演算子リロードコードでは、this->idは親ノード、s.idは新しく挿入されたサブノードです.もしこれがid>s.idの場合、trueを返すために交換されます.つまり、このプロセスを繰り返すと、ルートノードに最小の値が表示されます.#include <iostream>
#include <queue>
using namespace std;
struct Student {
int id;
int math, eng;
Student(int num, int m, int e) : id(num), math(m), eng(e) {}
// 학번이 작을수록 top에 위치하도록
bool operator < (const Student s) const {
// 부모 노드가 자식 노드보다 크면 swap
return this->id > s.id;
}
};
int main() {
priority_queue<Student> pq;
// 학번이 가장 작은 원소가 top에 위치함.
pq.push(Student(16, 100, 50));
pq.push(Student(20, 60, 50));
pq.push(Student(21, 80, 50));
pq.push(Student(18, 90, 50));
pq.push(Student(17, 70, 40));
while (!pq.empty()) {
Student s = pq.top();
cout << "[학번, 수학 , 영어]: " << s.id << ' ' << s.math <<
' ' << s.eng << '\n';
pq.pop();
}
return 0;
}
[学号,数学,英語]:1610050
[学号,数学,英語]:177040
[学号,数学,英語]:189050
[学号,数学,英語]:20 60 50
[学号,数学,英語]:218050
cmp構造を定義してソート条件を変更
優先キュー宣言で使用されるgreat、lessは実際には構造体であるため、このセクションにカスタム構造体を追加するとソート基準を変更できます.#include <iostream>
#include <queue>
using namespace std;
struct Student {
int id;
int math, eng;
Student(int num, int m, int e) : id(num), math(m), eng(e) {}
};
// 학번이 클수록 top에 위치하도록
struct cmp {
bool operator() (Student a, Student b) {
// 부모 노드가 자식 노드보다 작으면 swap
return a.id < b.id;
}
};
int main() {
priority_queue<Student, vector<Student>, cmp> pq;
// 학번이 가장 큰 원소가 top에 위치함.
pq.push(Student(16, 100, 50));
pq.push(Student(20, 60, 50));
pq.push(Student(21, 80, 50));
pq.push(Student(18, 90, 50));
pq.push(Student(17, 70, 40));
while (!pq.empty()) {
Student ts = pq.top(); pq.pop();
cout << "[학번, 수학 , 영어]: " << ts.id << ' ' << ts.math <<
' ' << ts.eng << '\n';
}
return 0;
}
#include <iostream>
#include <queue>
using namespace std;
int main() {
// priority_queue<int, vector<int>, less<int>> pq;
priority_queue<int> pq; // 내림차순
// 원소 삽입 (가장 큰 값이 top에 오도록)
pq.push(4);
pq.push(7);
pq.push(3);
pq.push(1);
pq.push(10);
cout << pq.size() << "\n"; // 5
while (!pq.empty()) {
cout << pq.top() << " "; // 10 7 4 3 1
pq.pop();
}
return 0;
}
#include <iostream>
#include <queue>
using namespace std;
int main() {
// 오름차순
priority_queue<int, vector<int>, greater<int>> pq;
// 원소 삽입 (가장 작은 값이 top에 오도록)
pq.push(4);
pq.push(7);
pq.push(3);
pq.push(1);
pq.push(10);
cout << pq.size() << "\n"; // 5
while (!pq.empty()) {
cout << pq.top() << " "; // 1 3 4 7 10
pq.pop();
}
return 0;
}
#include <iostream>
#include <queue>
using namespace std;
int main() {
priority_queue<int> pq;
// 음수로 변환해서 원소 삽입
pq.push(-4);
pq.push(-7);
pq.push(-3);
pq.push(-1);
pq.push(-10);
cout << pq.size() << "\n"; // 5
// 절댓값이 작은 원소부터 출력되도록 (오름차순)
while (!pq.empty()) {
cout << -pq.top() << " "; // 1 3 4 7 10
pq.pop();
}
return 0;
}
https://www.acmicpc.net/problem/11286
#include <iostream>
#include <queue>
using namespace std;
int main() {
cin.sync_with_stdio(0);
cin.tie(0);
int n;
cin >> n;
// pair의 first를 기준으로,
// 절댓값이 가장 작은 원소가 우선순위 큐의 top에 위치함.
// 출력할 때는 절댓값이 아닌 원래 값으로 출력
priority_queue<pair<int, int>, vector<pair<int, int>>, greater<pair<int, int>>> pq;
int x;
for (int i = 0; i < n; i++) {
cin >> x;
if (x == 0) {
if (pq.empty())
cout << "0\n";
else {
cout << pq.top().second << "\n";
pq.pop();
}
}
else {
// 절댓값이 작을수록 top에 위치하도록
pq.push({ abs(x), x });
}
}
return 0;
}
演算子を使用したソート構造の再ロード
生徒の学号を小さくしたいほど優先度Qのトップに入るにはどうすればいいのでしょうか.
優先度キューの内部はhipによって実現され、ルートノードの値が最も高い場合は最小hip、値が最も高い場合は最大hipである.
優先キューは、新しい要素が挿入されたときの親ノードとサイズを比較することで、2つのノードを交換するかどうかを決定します.親ノードのキー値が常に子ノードのキー値(最小ヒップ)より小さいか大きい場合は、交換されません.
次の演算子リロードコードでは、this->idは親ノード、s.idは新しく挿入されたサブノードです.もしこれがid>s.idの場合、trueを返すために交換されます.つまり、このプロセスを繰り返すと、ルートノードに最小の値が表示されます.#include <iostream>
#include <queue>
using namespace std;
struct Student {
int id;
int math, eng;
Student(int num, int m, int e) : id(num), math(m), eng(e) {}
// 학번이 작을수록 top에 위치하도록
bool operator < (const Student s) const {
// 부모 노드가 자식 노드보다 크면 swap
return this->id > s.id;
}
};
int main() {
priority_queue<Student> pq;
// 학번이 가장 작은 원소가 top에 위치함.
pq.push(Student(16, 100, 50));
pq.push(Student(20, 60, 50));
pq.push(Student(21, 80, 50));
pq.push(Student(18, 90, 50));
pq.push(Student(17, 70, 40));
while (!pq.empty()) {
Student s = pq.top();
cout << "[학번, 수학 , 영어]: " << s.id << ' ' << s.math <<
' ' << s.eng << '\n';
pq.pop();
}
return 0;
}
[学号,数学,英語]:1610050
[学号,数学,英語]:177040
[学号,数学,英語]:189050
[学号,数学,英語]:20 60 50
[学号,数学,英語]:218050
cmp構造を定義してソート条件を変更
優先キュー宣言で使用されるgreat、lessは実際には構造体であるため、このセクションにカスタム構造体を追加するとソート基準を変更できます.#include <iostream>
#include <queue>
using namespace std;
struct Student {
int id;
int math, eng;
Student(int num, int m, int e) : id(num), math(m), eng(e) {}
};
// 학번이 클수록 top에 위치하도록
struct cmp {
bool operator() (Student a, Student b) {
// 부모 노드가 자식 노드보다 작으면 swap
return a.id < b.id;
}
};
int main() {
priority_queue<Student, vector<Student>, cmp> pq;
// 학번이 가장 큰 원소가 top에 위치함.
pq.push(Student(16, 100, 50));
pq.push(Student(20, 60, 50));
pq.push(Student(21, 80, 50));
pq.push(Student(18, 90, 50));
pq.push(Student(17, 70, 40));
while (!pq.empty()) {
Student ts = pq.top(); pq.pop();
cout << "[학번, 수학 , 영어]: " << ts.id << ' ' << ts.math <<
' ' << ts.eng << '\n';
}
return 0;
}
#include <iostream>
#include <queue>
using namespace std;
struct Student {
int id;
int math, eng;
Student(int num, int m, int e) : id(num), math(m), eng(e) {}
// 학번이 작을수록 top에 위치하도록
bool operator < (const Student s) const {
// 부모 노드가 자식 노드보다 크면 swap
return this->id > s.id;
}
};
int main() {
priority_queue<Student> pq;
// 학번이 가장 작은 원소가 top에 위치함.
pq.push(Student(16, 100, 50));
pq.push(Student(20, 60, 50));
pq.push(Student(21, 80, 50));
pq.push(Student(18, 90, 50));
pq.push(Student(17, 70, 40));
while (!pq.empty()) {
Student s = pq.top();
cout << "[학번, 수학 , 영어]: " << s.id << ' ' << s.math <<
' ' << s.eng << '\n';
pq.pop();
}
return 0;
}
優先キュー宣言で使用されるgreat、lessは実際には構造体であるため、このセクションにカスタム構造体を追加するとソート基準を変更できます.
#include <iostream>
#include <queue>
using namespace std;
struct Student {
int id;
int math, eng;
Student(int num, int m, int e) : id(num), math(m), eng(e) {}
};
// 학번이 클수록 top에 위치하도록
struct cmp {
bool operator() (Student a, Student b) {
// 부모 노드가 자식 노드보다 작으면 swap
return a.id < b.id;
}
};
int main() {
priority_queue<Student, vector<Student>, cmp> pq;
// 학번이 가장 큰 원소가 top에 위치함.
pq.push(Student(16, 100, 50));
pq.push(Student(20, 60, 50));
pq.push(Student(21, 80, 50));
pq.push(Student(18, 90, 50));
pq.push(Student(17, 70, 40));
while (!pq.empty()) {
Student ts = pq.top(); pq.pop();
cout << "[학번, 수학 , 영어]: " << ts.id << ' ' << ts.math <<
' ' << ts.eng << '\n';
}
return 0;
}
Reference
この問題について([C++]優先順位queueコンテナのデフォルトの使い方), 我々は、より多くの情報をここで見つけました https://velog.io/@jxlhe46/C-priorityqueue-컨테이너-기본-사용법テキストは自由に共有またはコピーできます。ただし、このドキュメントのURLは参考URLとして残しておいてください。
Collection and Share based on the CC Protocol