STLコンテナ
CoddyのC++ジャーニー「オブジェクト指向プログラミング」セクションの一部。レッスン 71/104。
STL containersは、オブジェクトのコレクションを格納し、整理するテンプレートクラスです。各containerの種類は、異なるaccessパターンや操作に合わせて最適化されています。ニーズに合ったcontainerを選択することで、プログラムのパフォーマンスに大きな影響を与えられます。
シーケンスコンテナは要素を特定の順序で保持します:
#include <vector>
#include <list>
std::vector<int> vec = {1, 2, 3}; // 動的配列、高速なランダムアクセス
vec.push_back(4); // 末尾に追加: O(1) 償却
int x = vec[2]; // インデックスによるアクセス: O(1)
std::list<int> lst = {1, 2, 3}; // 双方向連結リスト
lst.push_front(0); // 先頭に追加: O(1)
lst.push_back(4); // 末尾に追加: O(1)連想コンテナは高速な検索のためにelementsをソート順で格納します:
#include <map>
#include <set>
std::set<int> s = {3, 1, 4, 1}; // 一意のソート済み要素: {1, 3, 4}
s.insert(2); // 挿入: O(log n)
bool found = s.count(3); // 存在確認: O(log n)
std::map<std::string, int> ages; // キーと値のペア、キーでソート
ages["Alice"] = 25; // 挿入/更新: O(log n)
ages["Bob"] = 30;
std::cout << ages["Alice"]; // アクセス: O(log n)順序なし containers はハッシュテーブルを使用するため、平均ケースの検索がさらに高速です:
#include <unordered_map>
std::unordered_map<std::string, int> scores;
scores["player1"] = 100; // 挿入: O(1) 平均
scores["player2"] = 200;
std::cout << scores["player1"]; // アクセス: O(1) 平均高速なランダムアクセスが必要な場合は vector、中央への頻繁な挿入には list、ソートされたデータが必要な場合は map/set、検索速度が重要で順序が問題にならない場合は unordered_map を使用します。
チャレンジ
簡単異なるSTLコンテナがそれぞれ異なる目的に役立つことを示す、学生の成績管理システムを構築しましょう。複数のコンテナ型を使って学生データを効率的に整理し、それぞれのタスクに適したコンテナを選択します。
コードを整理するために、2つのファイルを作成します。
GradeManager.h:複数のSTLコンテナを使用して学生情報を管理するGradeManagerクラスを定義します。クラスでは、次のものを使用します。
- 追加された順序で学生名を格納する
std::vector<std::string> - 各学生名をその成績に関連付ける
std::map<std::string, int> - 割り当てられたすべての重複しない成績を追跡する
std::set<int>
次のメソッドをImplementします。
addStudent(const std::string& name, int grade):学生とその成績を3つすべてのコンテナに追加しますgetGrade(const std::string& name):mapを使用して、指定された学生名の成績を返しますprintRoster():追加された順序で、すべての学生名を1行ずつ(vectorから)出力しますprintGrades():すべての学生とその成績をalphabetical orderで出力します(mapが自動的に処理します)。各行をname: gradeの形式にしますprintUniqueGrades():すべての重複しない成績をascending orderで出力します(setが処理します)。成績はスペースで区切り、最後に改行を付けます
- 追加された順序で学生名を格納する
main.cpp:入力を読み取り、それぞれのコンテナ型が異なる目的に役立つことを示します。6つの入力を読み取ります(それぞれ別の行に入力します)。
- First student name
- First student grade (integer)
- Second student name
- Second student grade (integer)
- Third student name
- Third student grade (integer)
GradeManagerをCreateし、3人の学生をすべて追加します。その後、異なるコンテナの動作を示します。Roster (insertion order):を出力し、続けてprintRoster()を呼び出しますGrades (alphabetical):を出力し、続けてprintGrades()を呼び出しますUnique grades:を出力し、続けてprintUniqueGrades()を呼び出します- 2人目の学生の成績をLook upし、
<name>'s grade: <grade>を出力します
たとえば、入力がCharlie、85、Alice、90、Bob、85の場合:
Roster (insertion order):
Charlie
Alice
Bob
Grades (alphabetical):
Alice: 90
Bob: 85
Charlie: 85
Unique grades:
85 90
Alice's grade: 90vectorはinsertion order(Charlie、Alice、Bob)を保持し、mapはkeyによって自動的にソートし(Alice、Bob、Charlie)、setはソートされた順序で重複しない値だけを格納する(85は2回ではなく1回だけ現れる)ことに注目してください。それぞれのコンテナ型は、異なるタスクで力を発揮します。
自分で試してみよう
#include <iostream>
#include <string>
#include "GradeManager.h"
using namespace std;
int main() {
// 3人の学生の入力を読み取る
string name1, name2, name3;
int grade1, grade2, grade3;
cin >> name1;
cin >> grade1;
cin >> name2;
cin >> grade2;
cin >> name3;
cin >> grade3;
// TODO: GradeManagerオブジェクトを作成する
// TODO: 3人の学生すべてをGradeManagerに追加する
// TODO: Print "Roster (insertion order):" and call printRoster()
// TODO: Print "Grades (alphabetical):" and call printGrades()
// TODO: Print "Unique grades:" and call printUniqueGrades()
// TODO: 2人目の学生の成績を調べて "<name>'s grade: <grade>" を出力する
return 0;
}
このレッスンには短いクイズがあります。レッスンを始めて解答し、進捗を記録しましょう。
オブジェクト指向プログラミングのすべてのレッスン
3コンストラクタとデストラクタ
デフォルトコンストラクタパラメータ付きコンストラクタコピーコンストラクタムーブコンストラクタコンストラクタ初期化リスト委譲コンストラクタデストラクタ徹底解説Rule of Three / Five / Zero復習 - Stringクラス6演算子オーバーロード
演算子オーバーロード入門算術演算子のオーバーロード比較演算子のオーバーロードストリーム演算子代入演算子のオーバーロード[] と () の演算子オーバーロード型変換演算子復習 - Matrixクラス自分で練習してみよう: C++オンラインコンパイラ