map

■概要

mapはSTLコンテナの1種で連想配列テンプレートクラスです。

●連想配列
	連想配列とはjavascriptやphp、perlなどで使われている配列です。
	通常の配列との違いは数値以外の値(文字列)をインデックスに使用できることです。

	例:
		// 連想配列 (javascript)
		var condition = new Object();
		condition['朝'] = '悪い';
		condition['昼'] = 'やや悪い';
		condition['晩'] = '若干悪い';

		console.log("朝 => %s", condition['朝']);
		console.log("昼 => %s", condition['昼']);
		console.log("晩 => %s", condition['晩']);

		出力結果:
			朝 => 悪い
			昼 => やや悪い
			晩 => 若干悪い

		通常の配列は先頭のアドレスとインデックス番号によるオフセットで
		要素を管理していますが、連想配列は要素とその要素に紐付いた値を
		1つのペアとして扱っており、紐付いた値を利用して
		要素を管理しています。
		この要素に紐付いた値のことをキーと呼んでいます。

■使用方法

●ヘッダファイル
	mapを使用するには<map>をインクルードする必要があります。

	例:
		#include <map>

●宣言
	mapはテンプレートクラスなので、変数宣言時に<>を使用して
	キーと要素の型を指定して宣言します。

	・書式
		・書式例
			std::map<キーの型, 要素の型> 変数名;

		・具体例
			// キー:string、要素:string
			std::map<std::string, std::string> str_list;

●要素追加
	要素の追加は直接キー指定して値を代入する方法と、
	insert関数を使用した方法があります。

	・直接キー指定して値を代入
		「map[キー] = 値」を行うとキーが存在しなかった場合、
		新規要素として追加されます。

		例:
			std::map<int, int>map_list;
			printf("map size => %d\n", map_list.size());
			map_list[10] = 100;
			printf("map size => %d\n", map_list.size());

			出力結果:
				map size => 0
				map size => 1

	・insert関数
		insert関数はオーバーロードが数多く用意されています。
		今回は3種類紹介します。

		map<キーの型, 要素の型>::value_type(キー, 値):
			std::map<int, int>map_list;
			printf("map size => %d\n", map_list.size());
			map_list.insert(std::map<int, int>::value_type(10, 100));
			printf("map size => %d\n", map_list.size());
			printf("map_list[10] => %d\n", map_list[10]);

			出力結果:
				map size => 0
				map size => 1
				map_list[10] => 100

		pair<キーの型, 要素の型>(キー, 値):
			std::map<std::string, int>map_list;
			printf("map size => %d\n", map_list.size());
			map_list.insert(std::pair<std::string, int>("キー", 30));
			printf("map size => %d\n", map_list.size());
			printf("map_list[\"キー\"] => %d\n", map_list["キー"]);

			出力結果:
				map size => 0
				map size => 1
				map_list["キー"] => 30

		make_pair(キー, 値):
			std::map<std::string, std::string>map_list;
			printf("map count => %d\n", map_list.size());
			map_list.insert(std::make_pair("キー", "値"));
			printf("map count => %d\n", map_list.size());
			printf("map_list[\"キー\"] => %s\n", map_list["キー"].c_str());
					
			出力結果:
				map size => 0
				map size => 1
				map_list["キー"] => 値

	・追加の順番
		mapに追加された要素はキーの値を元にして自動的に昇順でソートされます。

		例:
			std::map<std::string, std::string>map_list;
			map_list.insert(std::make_pair("b", "い"));
			map_list.insert(std::make_pair("e", "お"));
			map_list.insert(std::make_pair("a", "あ"));
			map_list.insert(std::make_pair("d", "え"));
			map_list.insert(std::make_pair("c", "う"));

			for (auto itr = map_list.begin(); itr != map_list.end(); itr++)
			{
				printf("key = %s, ", itr->first.c_str());
				printf"(val = %s\n", itr->second.c_str());
			}

			出力結果:
				key = a, val = あ
				key = b, val = い
				key = c, val = う
				key = d, val = え
				key = e, val = お

●要素アクセス
	「●要素追加」で既に行っていますが、mapの要素へのアクセスは
	変数名[キー]で参照、代入ができます。

	例:
		std::map<int, int> map_list;
		map_list[5] = 330;
		printf("map_list[5] => %d\n", map_list[5]);
		map_list[10] = 200;
		printf("map_list[5] => %d\n", map_list[5]);

		出力結果:
			map_list[5] => 330
			map_list[5] => 200

●イテレータ使用
	mapもSTLの1種なので要素の確認をする場合は
	イテレータを使用することができます。
	mapのイテレータには「first」と「second」が用意されており、
	firstにキーが、secondに要素が格納されています。

	例:
		std::map<std::string, std::string>map_list;
		map_list.insert(std::make_pair("a", "あ"));
		map_list.insert(std::make_pair("b", "い"));
		map_list.insert(std::make_pair("c", "う"));
		map_list.insert(std::make_pair("d", "え"));
		map_list.insert(std::make_pair("e", "お"));

		for (auto itr = map_list.begin(); itr != map_list.end(); itr++)
		{
			printf("key = %s, ", itr->first.c_str());
			printf("val = %s\n", itr->second.c_str());
		}

		出力結果:
			key = a, val = あ
			key = b, val = い
			key = c, val = う
			key = d, val = え
			key = e, val = お

●要素削除
	要素の削除はerase関数を使用して行います。

	・キー指定
		キー指定は引数にキーを指定することで指定した要素が削除できます。

		例:
			std::map<std::string, std::string>map_list;
			map_list.insert(std::make_pair("a", "あ"));
			map_list.insert(std::make_pair("b", "い"));
			map_list.insert(std::make_pair("c", "う"));
			map_list.insert(std::make_pair("d", "え"));
			map_list.insert(std::make_pair("e", "お"));

			map_list.erase("a");

			for (auto itr = map_list.begin(); itr != map_list.end(); itr++)
			{
				printf("key = %s, ", itr->first.c_str());
				printf("val = %s\n", itr->second.c_str());
			}

			出力結果:
				key = b, val = い
				key = c, val = う
				key = d, val = え
				key = e, val = お

	・イテレータ指定
		イテレータ指定は引数に削除したい要素のイテレータを指定することで、
		指定した要素が削除されます。

		例:
			std::map<std::string, std::string>map_list;
			map_list.insert(std::make_pair("a", "あ"));
			map_list.insert(std::make_pair("b", "い"));
			map_list.insert(std::make_pair("c", "う"));
			map_list.insert(std::make_pair("d", "え"));
			map_list.insert(std::make_pair("e", "お"));

			for (auto itr = map_list.begin(); itr != map_list.end(); itr++)
			{
				if (strcmp(itr->second.c_str(), "え") == 0)
				{
					// えの要素を削除
					map_list.erase(itr);
					break;
				}
			}

			for (auto itr = map_list.begin(); itr != map_list.end(); itr++)
			{
				printf("key = %s, ", itr->first.c_str());
				printf("val = %s\n", itr->second.c_str());
			}

			出力結果:
				key = a, val = あ
				key = b, val = い
				key = c, val = う
				key = e, val = お

	・イテレータ(範囲指定)
		引数に削除したい範囲を指定することで、その範囲の要素を削除できます。

		例:
			std::map<std::string, std::string>map_list;
			map_list.insert(std::make_pair("a", "あ"));
			map_list.insert(std::make_pair("b", "い"));
			map_list.insert(std::make_pair("c", "う"));
			map_list.insert(std::make_pair("d", "え"));
			map_list.insert(std::make_pair("e", "お"));

			for (auto itr = map_list.begin(); itr != map_list.end(); itr++)
			{
				if (strcmp(itr->second.c_str(), "う") == 0)
				{
					// "う"~最後の要素までを削除
					map_list.erase(itr, map_list.end());
					break;
				}
			}

			for (auto itr = map_list.begin(); itr != map_list.end(); itr++)
			{
				printf("key = %s, ", itr->first.c_str());
				printf("val = %s\n", itr->second.c_str());
			}

			出力結果:
				key = a, val = あ
				key = b, val = い