C++の標準ライブラリであるSTL(Standard Template Library)には、さまざまなデータ構造(コンテナ)が含まれています。これらのコンテナを活用することで、効率的にデータを管理し、プログラムを簡潔に記述することができます。
本記事では、STLの主要なコンテナについて、その特徴や基本操作、実践的なサンプルコードとともに解説していきます。
1. STLのコンテナの種類
STLのコンテナは大きく分けて3つのカテゴリーに分類されます。
シーケンスコンテナ(Sequence Containers)
データを順番に格納するコンテナ。
std::vector
(動的配列)std::deque
(両端キュー)std::list
(双方向リスト)std::forward_list
(単方向リスト)std::array
(固定長配列)連想コンテナ(Associative Containers)
キーと値のペアを管理するコンテナ。
std::map
(キーの順序を保持)std::multimap
(キーの重複を許可)std::set
(重複を許さない集合)std::multiset
(重複を許可する集合)無順序連想コンテナ(Unordered Associative Containers)
ハッシュテーブルを使用した連想コンテナ。
std::unordered_map
(順序なしのマップ)std::unordered_multimap
(順序なし・キー重複可)std::unordered_set
(順序なし集合)std::unordered_multiset
(順序なし・重複可)2. map(連想配列)
mapの基本操作
map
はキーと値のペアを管理する連想配列であり、辞書のようなデータ構造です。
#include <bits/stdc++.h>
using namespace std;
int main() {
map<string, int> score;
score["Alice"] = 100;
score["Bob"] = 89;
score["Charlie"] = 95;
cout << score.at("Alice") << endl;
cout << score.at("Bob") << endl;
cout << score.at("Charlie") << endl;
}
操作一覧
map[key] = value;
(O(logN))map.erase(key);
(O(logN))map.at(key);
(O(logN))map.count(key);
(O(logN))map.size();
(O(1))3. queue(待ち行列)
queue
は先入れ先出し(FIFO)のデータ構造です。
#include <bits/stdc++.h>
using namespace std;
int main() {
queue<int> q;
q.push(10);
q.push(3);
q.push(6);
q.push(1);
while (!q.empty()) {
cout << q.front() << endl;
q.pop();
}
}
操作一覧
queue.push(value);
(O(1))queue.front();
(O(1))queue.pop();
(O(1))queue.size();
(O(1))4. priority_queue(優先度付きキュー)
priority_queue
は最大値(または最小値)を素早く取得できるデータ構造です。
#include <bits/stdc++.h>
using namespace std;
int main() {
priority_queue<int> pq;
pq.push(10);
pq.push(3);
pq.push(6);
pq.push(1);
while (!pq.empty()) {
cout << pq.top() << endl;
pq.pop();
}
}
小さい順に取り出す priority_queue
priority_queue<int, vector<int>, greater<int>> pq;
5. set(集合)
set
は重複のないデータの集合を扱うコンテナです。
#include <bits/stdc++.h>
using namespace std;
int main() {
set<int> S;
S.insert(3);
S.insert(7);
S.insert(8);
S.insert(10);
S.insert(3);
cout << "size: " << S.size() << endl;
if (S.count(7)) cout << "found 7" << endl;
}
6. stack(スタック)
stack
は後入れ先出し(LIFO)のデータ構造です。
#include <bits/stdc++.h>
using namespace std;
int main() {
stack<int> s;
s.push(10);
s.push(1);
s.push(3);
cout << s.top() << endl;
s.pop();
cout << s.top() << endl;
}
7. lower_bound / upper_bound
二分探索を利用してソート済み配列内の要素を検索します。
#include <bits/stdc++.h>
using namespace std;
int main() {
vector<int> a = {0, 10, 13, 14, 20};
cout << *lower_bound(a.begin(), a.end(), 12) << endl;
cout << *upper_bound(a.begin(), a.end(), 10) << endl;
}
8. まとめ
STLのコンテナは、適切なデータ構造を選択することで、より効率的なプログラムを書くことができます。各コンテナの特性を理解し、適材適所で活用しましょう!