404 Not Found

404 Not Found


nginx

STLコンテナ

[前のレッスンでは]、[templateについて学びました]――[これにより]関数[や]クラスが[任意の]型に対応できるようになります。

[ただし、実際の]プロジェクト[では]、[自分で]コンテナ([例えば動的]配列や[リンクリスト]など)を[書く必要はありません]。

C++の[標準]テンプレート[ライブラリ](STL)には、[すぐに使える]コンテナが[用意されている]ので、[そのまま使えばいい]!


1. STLとは?

STL(Standard Template Library、[標準]テンプレート[ライブラリ])は、C++の[標準ライブラリの一部]であり、以下を[含んでいます]:

[構成要素] [役割]
コンテナ [データ保存] std::vectorstd::array
イテレータ [コンテナの反復処理] begin()end()
アルゴリズム [操作データ] std::sortstd::find
functionobject [カスタム比較ロジック] std::lessstd::greater

💡 [要点]: STLはテンプレートで[実装されている]ため、[任意の]型をサポートできます。



2. ベクトル([最もよく使われる])

(1) 2.1 ベクトルとは何か?

std::vector [はい][動的]配列——[サイズが自動的に拡大する]。

[比較] [通常]配列 ベクトル
[サイズ] [固定] [動的]
メモリ スタック[または]ヒープ ヒープ
[要素へのアクセス] arr[i] vec[i] [または] vec.at(i)
[おすすめ度] ⭐⭐ ⭐⭐⭐⭐⭐

▶ サンプル 1: vector [基本用法] (難易度 ⭐)

CPP
#include iostream
#include vector

int main() {
 // int vector
 std::vectorint vec = {1, 2, 3, 4, 5};
 
 // ...
 std::cout << ":" << vec[0] << std::endl;
 std::cout << ":" << vec.at(1) << std::endl;
 
 // ...
 vec[0] = 100;
 
 // ...
 std::cout << ":" << vec.size() << std::endl;
 
 return 0;
}
▶ 試してみよう

💡 [ヒント]: vec.at(i) [は][境界外チェックを行う],[境界外の場合は]例外をスローする;vec[i] [はチェックを行わない],[効率が高い]。


(2) 2.2 [要素の追加と削除]

CPP
#include iostream
#include vector

int main() {
 std::vectorint vec;
 
 // ...
 vec.push_back(10);
 vec.push_back(20);
 vec.push_back(30);
 
 // ...
 vec.pop_back();
 
 // ...
 vec.insert(vec.begin() + 1, 15); // 15
 
 // ...
 vec.erase(vec.begin() + 1); // ...
 
 return 0;
}

(3) 2.3 [ベクトルの反復処理]

[方法1]:[添字による反復]([最も一般的])

CPP
#include iostream
#include vector

int main() {
 std::vectorint vec = {1, 2, 3, 4, 5};
 
 for (size_t i = 0; i < vec.size(); i++) {
 std::cout << vec[i] << " ";
 }
 std::cout << std::endl;
 
 return 0;
}

[方法2]:[適用範囲] for(C++11、[推奨])

CPP
#include iostream
#include vector

int main() {
 std::vectorint vec = {1, 2, 3, 4, 5};
 
 for (int x : vec) {
 std::cout << x << " ";
 }
 std::cout << std::endl;
 
 return 0;
}

[方法3]:イテレータ([後述])

CPP
#include iostream
#include vector

int main() {
 std::vectorint vec = {1, 2, 3, 4, 5};
 
 for (auto it = vec.begin(); it != vec.end(); ++it) {
 std::cout << *it << " ";
 }
 std::cout << std::endl;
 
 return 0;
}

💡 [おすすめ]: [優先的に使用][範囲] for(C++11)、[最も簡潔]。



3. array([固定サイズ]array)

(1) 3.1 配列とは何か?

std::array [これは][固定サイズ][の]配列であり、[しかし] [通常の]配列よりも[安全]です。

[比較] [通常]配列 配列
[サイズ] [知っておくべきこと] [使用方法] size() [入手方法]
[退化してしまうか]ポインタ [はい] [いいえ]
[おすすめ度] ⭐⭐ ⭐⭐⭐⭐

▶ サンプル 2: array [基本用法] (難易度 ⭐)

CPP
#include iostream
#include array

int main() {
 // 5 int array
 std::array<int, 5> arr = {1, 2, 3, 4, 5};
 
 // ...
 std::cout << ":" << arr[0] << std::endl;
 
 // ...
 std::cout << ":" << arr.size() << std::endl;
 
 return 0;
}
▶ 試してみよう

💡 [要点]: std::array [のサイズは]コンパイル時に[決定][される]もので、[変更することはできない]。



4. deque([両端キュー])

(1) 4.1 dequeとは何か?

std::deque [はい][両端キュー]――[両端]で[要素を]素早く[追加]・[削除]できる。

[操作] vector deque
[末尾追加] O(1) O(1)
[先頭に追加] O(n) O(1)
[ランダムアクセス] O(1) O(1)

▶ サンプル 3: deque [基本用法] (難易度 ⭐⭐)

CPP
#include iostream
#include deque

int main() {
 std::dequeint dq;
 
 // ...
 dq.push_back(10);
 dq.push_back(20);
 
 // ...
 dq.push_front(5);
 dq.push_front(1);
 
 // dq:1, 5, 10, 20
 
 for (int x : dq) {
 std::cout << x << " ";
 }
 std::cout << std::endl;
 
 return 0;
}
▶ 試してみよう

5. リスト([双方向連結リスト])

(1) 5.1 「リスト」とは何か?

std::list [はい][双方向連結リスト]——[各要素には、前後の要素の]アドレスが格納されている。

[比較] ベクトル リスト
[ランダムアクセス] O(1) ❌ [非対応]
[挿入]/[削除] O(n) O(1)
メモリ[使用量] [小] [大]([各要素につき2つのポインタを追加])

▶ サンプル 4: list [基本用法] (難易度 ⭐⭐)

CPP
#include iostream
#include list

int main() {
 std::listint lst = {1, 2, 3, 4, 5};
 
 // ...
 lst.push_front(0);
 
 // ...
 lst.push_back(6);
 
 // 3
 lst.remove(3);
 
 for (int x : lst) {
 std::cout << x << " ";
 }
 std::cout << std::endl;
 
 return 0;
}
▶ 試してみよう

6. forward_list([単方向連結リスト])

(1) 6.1 forward_list とは何か?

std::forward_list [はい][単方向連結リスト]——[各要素には、1つの要素の]アドレスだけが格納される。

[比較] リスト フォワードリスト
メモリ[使用量] [大きい] [小さい]
[前方へ走査できますか]?
[おすすめ度] ⭐⭐⭐⭐ ⭐⭐([特定の場面向け])

💡 [アドバイス]: [確実に]**[後方のみを走査すればよい]と[確信している場合]を除き、[そうでない場合は] std::listを使用してください。



7. コンテナ【選び方のガイド】

[シーン] [おすすめ]コンテナ
[動的なサイズが必要] std::vector
[サイズ固定]、[保持] C [スタイル] std::array
[ヘッダーに素早く追加]/[削除] std::deque
[頻繁に中間への挿入]/[削除]が必要 std::list
[後ろに向かって走査するだけでよい]、[かつメモリを節約する] std::forward_list

💡 [黄金律]: [優先して] std::vector を使用し、[[明確な理由]がある場合を除き]、[他のもの]を使用する。



8. 演習:[vector を使用して] 動的配列を実装する (難易度 ⭐⭐)

CPP
#include iostream
#include vector
#include string

struct Student {
 std::string name;
 int age;
 double score;
};

int main() {
 std::vectorStudent students;
 
 // ...
 students.push_back({"Alice", 20, 92.5});
 students.push_back({"Bob", 21, 88.0});
 students.push_back({"Charlie", 19, 95.0});
 
 // output
 for (const auto& s : students) {
 std::cout << ":" << s.name 
 << ",:" << s.age 
 << ",:" << s.score << std::endl;
 }
 
 return 0;
}

❓ よくある質問

Q:vector [と] array [の違いは何ですか]? A:> - vector [サイズ][動的]、[ヒープ]上に存在する > - array [サイズ][固定]、[スタック]上に存在する > > [選択のアドバイス]: [サイズが不確定な場合]、vectorを使用;[サイズが固定でかつ小さい場合]、 array [を使用]。 Q:[なぜ] vector [の反復処理には] for [範囲指定] が推奨されるのですか? A:[より簡潔] であり、[ループ条件] を[書き間違えにくい] からです。 > > // [従来の] for([書き間違えやすい]条件) > for (size_t i = 0; i < vec.size(); i++) { ... } > > // [範囲] for([簡潔]、[ミスが少ない]) > for (int x : vec) { ... } > Q:list [と] vector [どちらが速い]? A:[状況による]: > - [もし][ランダムアクセス]が必要なら(vec[100])、 vector [速い] > - [中間への挿入]/[削除]が必要な場合、list [速い]


Q:STL containersについて最も重要なことは何ですか? A:まず核心概念を理解し、その後実践的な例で練習することが重要です。

📖 まとめ


📝 練習問題

  1. 初心者(難易度 ⭐): [入力] std::vectorint [保存] 5 [個の整数],[それらを順に処理して]出力する。

  2. 中級(難易度 ⭐⭐): [用] std::vectorstd::string [3つの]文字列を保存し、[ユーザーに]入力させ、[その後]出力する。

  3. 上級(難易度 ⭐⭐⭐): [用] std::deque [実現]「回文 [検出]」:


9. 🚀 次は

[STLコンテナ[の基礎]を学びました]。[次は] STLアルゴリズム([第]35[回])を学びます―― [標準ライブラリが提供する]algorithmを使って[コンテナを操作]し、[自分でソートや検索のコードを書く必要はありません]……

Web-Tutorial.com

Web-Tutorial 技術チーム

複数の開発者によって共同維持されているプログラミングチュートリアルプラットフォーム。各チュートリアルは専門分野の開発者が執筆・レビューしています。正確で信頼性の高いコンテンツを目指しています — 問題を見つけた場合はお知らせください。

100%