地図で見る C++ 標準テンプレート ライブラリ (STL)

⚡ スマートサマリー

地図で見る C++ は、標準テンプレートライブラリの連想コンテナであり、要素をソートされたキーと値のペアとして格納します。各一意のキーは1つの値に対応し、高速な検索、挿入、および順序付き走査を可能にします。

  • おいおいおいそ️ 連想コンテナ: A C++ マップは、一意で自動的にソートされたキーを持つキーと値のペアとしてアイテムを保存します。
  • 🧩 ヘッダーと構文: マップヘッダーを含めてから、std::mapを宣言します。型付きペアを格納するための名前。
  • 🛠️ 組み込み関数: begin()、size()、empty()、insert()、find()、erase()、clear() はマップの内容を管理する関数です。
  • 🔄 反復: 双方向イテレータは、読み取りまたは削除のために、ソートされたキーの順序でマップ要素を走査します。
  • 🔑 固有のキー: 2つの要素はキーを共有できないため、マップは連想配列として理想的です。
  • 🤖 AI支援: GitHub Copilotや同様のAIアシスタントは、短いコメントからマップ宣言やループを自動生成します。

地図で見る C++ STL

マップとは何か C++?

In C++MAPとは、アイテムをマッピングされた形式で格納する連想コンテナです。マップ内の各アイテムは、キー値とマッピングされた値で構成されます。2つのマッピングされた値は、同じキー値を共有することはできません。

キー値は要素を一意にソートおよび識別するのに役立ち、マップ値は各キーに関連付けられたコンテンツを格納します。両者の型は異なる場合がありますが、メンバー型によって両方を含むペアにまとめられます。

コードを書く前に、なぜマップが適切なコンテナとしてよく使われるのかを知っておくと役立ちます。

std::map を使用する理由

地図を使う理由は以下のとおりです。

  • std::map は、選択されたソート基準に基づいてソートされた順序で、一意のキーのみを格納します。
  • キーを使用すれば、要素を簡単かつ迅速に検索できます。
  • 各キーにアタッチされる要素は XNUMX つだけです。
  • std::map は連想配列として使用できます。
  • std::mapは、平衡二分木を用いて実装可能です。

これらの利点を活用するには、まず宣言構文から始めましょう。

構文

std::map を宣言するには、次の構文を使用します。

std::map<key_datatype, value_datatype>map_name; 
  • その キーデータ型 マップキーのデータ型を示します。
  • その 値のデータ型 は、マップキーに対応する値のデータ型を示します。
  • その マップ名 マップの名前です。

具体的な例を挙げますと、以下の通りです。

map<string, int> my_map; 

my_mapという名前のマップを宣言しました。このマップのキーのデータ型は文字列、値のデータ型は整数になります。

メンバーの種類

メンバー関数は、パラメータまたは戻り値の型として、以下のメンバー型を使用できます。

  • キーの種類: キー(テンプレートの最初のパラメータ)
  • マップされたタイプ: T(テンプレートの2番目のパラメータ)
  • キー比較: (テンプレートの3番目のパラメータ)を比較する
  • アロケータのタイプ: Alloc(テンプレートの4番目のパラメータ)
  • 値の種類: ペア
  • 値の比較: 要素を比較するためのネストされた関数クラス
  • 参照: allocator_type::reference
  • const_reference: allocator_type::const_reference
  • ポインタ: allocator_type::pointer
  • const_pointer: allocator_type::const_pointer
  • イテレータ: value_type への双方向反復子
  • const_iterator: const value_type への双方向イテレータ
  • reverse_iterator: 逆反復子
  • const_reverse_iterator: 定数逆反復子
  • 違いの種類: ptrdiff_t
  • サイズタイプ: サイズ_t

std::map の組み込み関数

std::map には組み込み関数が付属しています。 これらには次のようなものがあります。

  • ベギン () – この関数は、マップの最初の要素へのイテレータを返します。
  • サイズ() – この関数はマップ内のアイテム数を返します。
  • 空の() – この関数は、マップが空かどうかを示すブール値を返します。
  • 挿入(ペア(キー、値)) この関数は、マップに新しいキーと値のペアを挿入します。
  • find(val) この関数は、val要素が見つかった場合はそのイテレータを返します。見つからない場合は、m.end()を返します。
  • erase(イテレータの位置) – この関数は、イテレータが指す位置にある項目を削除します。
  • 消去(const g) – この関数は、マップからキーと値のペアであるgを削除します。
  • 晴れ() この関数は、マップからすべてのアイテムを削除します。

定義された関数を用いて、反復処理から始めて、以下の例でそれらを実際に使用してみましょう。

マップ要素の反復処理

マップの要素を反復処理できます。そのためには、イテレータを作成してそれを使用するだけです。例えば、次のようになります。

#include <iostream>
#include <string>
#include <map> 

using namespace std;
int main() {

	map<int, string> Students;

	Students.insert(std::pair<int, string>(200, "Alice"));

	Students.insert(std::pair<int, string>(201, "John"));

	cout << "Map size is: " << Students.size() << endl;

	cout << endl << "Default map Order is: " << endl;

	for (map<int, string>::iterator it = Students.begin(); it != Students.end(); ++it) {

		cout << (*it).first << ": " << (*it).second << endl;
	}
}

出力:

C++ マップ反復の例1の出力

コードのスクリーンショットは次のとおりです。

C++ マップ反復の例1のコード

Code 説明:

  1. その機能を使用するには、iostream ヘッダー ファイルをコードに組み込みます。
  2. その関数を使用するには、文字列ヘッダー ファイルをコードに組み込みます。
  3. その機能を使用するには、マップ ヘッダー ファイルをコードに組み込みます。
  4. std 名前空間をコードに含めると、呼び出さずにそのクラスを使用できます。
  5. main() 関数を呼び出します。 { は関数本体の始まりを示します。
  6. Student という名前のマップを作成します。キーは整数、値は文字列になります。
  7. マップに値を挿入します。 キー 200 と値 Alice がマップに挿入されます。
  8. マップに値を挿入します。 キー 201 と値 John がマップに挿入されます。
  9. size() 関数を使用して、Students という名前のマップのサイズを取得します。これは 2 を返すはずです。
  10. コンソールにテキストを出力します。
  11. for ループを使用して it という名前の反復子を作成し、Students という名前のマップの要素を反復処理します。
  12. マップ Student の値をコンソールに出力します。
  13. for ループの本体の終わり。
  14. main() 関数の本体の終わり。

std::map へのデータの挿入

insert() 関数を使って、std::map に項目を追加できます。std::map のキーは一意でなければならないことに注意してください。

まず、各キーがマップ内に存在するかどうかを確認します。存在する場合は、エントリは挿入されず、既存のエントリのイテレータが返されます。存在しない場合は、エントリが挿入されます。

この機能には次のバリエーションがあります。

  • 挿入(ペア) このバリエーションでは、キーと値のペアがマップに挿入されます。
  • insert(start_itr, end_itr) このバリエーションでは、エントリは別のマップのstart_itrとend_itrで定義された範囲内に挿入されます。

insert_or_assign() 関数は insert() 関数と同じように動作しますが、指定されたキーが既にマップ内に存在する場合は、その値が変更されます。

#include <map>
#include <iostream>

using namespace std;

int main() {

	map<int, int> m{ {1,3} , {2,4} , {3,5} };

	m.insert({ 5, 6 });
	m.insert({ 1, 8 });

	m.insert_or_assign(1, 6);  
	
	cout << "Key\tElement\n";
	for (auto itr = m.begin(); itr != m.end(); ++itr) {
		cout << itr->first << '\t' << itr->second << '\n';
	}
	return 0;
}

出力:

C++ マップ挿入例2の出力

コードのスクリーンショットは次のとおりです。

C++ マップ挿入例2コード

Code 説明:

  1. その機能を使用するには、マップ ヘッダー ファイルをコードに組み込みます。
  2. その機能を使用するには、iostream ヘッダー ファイルをコードに組み込みます。
  3. std 名前空間をコードに含めると、呼び出さずにそのクラスを使用できます。
  4. main() 関数を呼び出します。 { は関数本体の始まりを示します。
  5. m という名前のマップを作成します。キーは整数、値は整数になります。 マップには XNUMX つのエントリが作成されました。
  6. 新しいエントリをマップ m に挿入します。 キー 5 と値 6 がマップに挿入されます。
  7. 既存のキーにエントリを作成しようとしています。 キー 1 はマップ内にすでに存在するため、エントリは作成されません。
  8. insert_or_assign() 関数を使用して、既存のエントリを挿入または変更します。キー 1 は既に存在するため、その値は 6 に変更されます。
  9. コンソールにテキストを出力します。 「\t」文字は水平方向のスペースを作成し、「\n」文字はマウス カーソルを次の行に移動します。
  10. 使用 forループ itr という名前の反復子を作成して、m という名前のマップの要素を反復処理します。
  11. マップ m の値をコンソールに出力します。 「\t」文字は、各キーとそれに対応する値の間に水平方向のスペースを作成します。 対照的に、「\n」文字は、反復のたびにマウス カーソルを次の行に移動します。
  12. for ループの本体の終わり。
  13. プログラムは正常に完了すると値を返す必要があります。
  14. main() 関数の本体の終わり。

マップで検索する

find() 関数を使うと、マップ内の要素をキーで検索できます。キーが見つからない場合は、関数は std::map::end を返します。それ以外の場合は、検索された要素のイテレータが返されます。

#include <iostream>
#include <string>
#include <map> 
using namespace std;
int main() {
	map<int, string> Students;
	Students.insert(std::pair<int, string>(200, "Alice"));
	Students.insert(std::pair<int, string>(201, "John"));
	std::map<int, string>::iterator it = Students.find(201);
	if (it != Students.end()) {
		std::cout << endl << "Key 201 has the value: => "<< Students.find(201)->second << '\n';
	}
}

出力:

C++ マップ検索例3出力

コードのスクリーンショットは次のとおりです。

C++ マップ検索例3コード

Code 説明:

  1. エラーを発生させずに関数を使用するには、iostream ヘッダー ファイルをコードに組み込みます。
  2. エラーを発生させずにその関数を使用するには、文字列ヘッダー ファイルをコードに含めます。
  3. エラーを発生させずにその機能を使用するには、マップ ヘッダー ファイルをコードに組み込みます。
  4. std 名前空間をコードに含めると、呼び出さずにそのクラスを使用できます。
  5. main() 関数を呼び出します。{ は main() 関数の本体の開始を示します。
  6. Student という名前のマップを作成します。このマップのキーは整数、値は文字列になります。
  7. マップに値を挿入します。 キー 200 と値 Alice がマップに挿入されます。
  8. マップに値を挿入します。 キー 201 と値 John がマップに挿入されます。
  9. キー 201 に関連付けられた値を探します。
  10. if ステートメントを使用して、キーの値が見つかったかどうかを確認します。
  11. コンソール上のテキストの横にキーの値を出力します。
  12. if ステートメントの本文の終わり。
  13. main() 関数の本体の終わり。

マップからのデータの削除

erase() 関数を使うと、マップから値を削除できます。削除する要素を指すイテレータを作成し、そのイテレータを erase() 関数に渡します。

#include <iostream>
#include <string>
#include <map>

using namespace std;
int main() {

	map<std::string, int> my_map;

	my_map.insert(std::make_pair("cow", 1));

	my_map.insert(std::make_pair("cat", 2));

	my_map["lion"] = 3;

	map<std::string, int>::iterator it = my_map.find("cat");

	my_map.erase(it);

	for (map<string, int>::iterator it = my_map.begin(); it != my_map.end(); ++it)

		cout << (*it).first << ": " << (*it).second << endl;

  return 0;
}

出力:

C++ マップ消去削除例4出力

コードのスクリーンショットは次のとおりです。

C++ マップ消去削除例4コード

Code 説明:

  1. その機能を使用するには、iostream ヘッダー ファイルをコードに組み込みます。
  2. その関数を使用するには、文字列ヘッダー ファイルをコードに組み込みます。
  3. その機能を使用するには、マップ ヘッダー ファイルをコードに組み込みます。
  4. std 名前空間をコードに含めると、呼び出さずにそのクラスを使用できます。
  5. main() 関数を呼び出します。{ は main() 関数の本体の開始を示します。
  6. my_map という名前のマップを作成します。このマップのキーは文字列、値は整数になります。
  7. マップ my_map に値を挿入します。 Cow のキーと 1 の値がマップに挿入されます。
  8. マップ my_map に値を挿入します。 Cat のキーと 2 の値がマップに挿入されます。
  9. ライオンのキーを使用して値 3 をマップ my_map に追加します。
  10. キー cat を探してマップ my_map を反復処理するイテレーターを作成します。
  11. イテレータが指す要素を削除します。
  12. イテレータを使用して、マップ my_map の要素を最初から最後まで順に処理します。
  13. マップ my_map の内容をコンソールに出力します。
  14. プログラムは正常に完了すると出力を返す必要があります。
  15. main() 関数の本体の終わり。

よくあるご質問

std::map は自己平衡二分探索木を使用してキーをソートし、O(log n) の操作時間を実現します。std::unordered_map はハッシュテーブルを使用して平均 O(1) の検索時間を実現しますが、キーは特定の順序で格納されません。順序付けのニーズに基づいて選択してください。

std::mapは通常、自己平衡二分探索木、多くの場合赤黒木として実装されます。これにより、キーはソートされた順序で保持され、挿入、削除、検索操作が対数時間で完了することが保証されます。

いいえ。std::mapは一意のキーのみを保持するため、既存のキーを挿入しても上書きされません。重複するキーが必要な場合は、複数の要素が同じキー値を共有できるstd::multimapを使用してください。

値の読み取りまたは割り当てには、map_name[key] を使用します。添え字演算子は、キーが存在しない場合にデフォルトのエントリを挿入します。at() メンバーは、キーが存在しない場合に例外をスローするため、より安全な選択肢となります。

3番目のテンプレート引数として、std::mapなどのカスタム比較器を渡します。 >。比較器が大きいほど、デフォルトの昇順ではなく、キーが最大値から最小値へと並べ替えられます。

std::mapはキーと値のペアを格納し、キーで値を検索しますが、std::setは一意のキーのみを格納し、関連付けられた値はありません。どちらも要素をソートして保持しますが、mapは各キーにデータを関連付けます。

はい。AIコーディングアシスタントは、短いプロンプトやコメントを、宣言、挿入呼び出し、イテレータループなどを含む、動作するstd::mapコードに変換します。コンパイルする前に、生成されたキーの型、順序、およびエッジケースを必ず確認してください。

Yes. GitHubコパイロット 入力すると、マップ宣言、挿入・検索呼び出し、反復ループなどが提案されます。繰り返し発生する定型コードの処理には優れていますが、構築前にキーの一意性とロジックを検証する必要があります。