1.c++-stl map詳細


mapはSTLの関連コンテナで、1対1(最初はキーワードと呼ぶことができ、各キーワードはmapに1回しか現れず、2番目はキーワードの値と呼ぶことができる)のデータ処理能力を提供します.この特性のため、1対1のデータを処理するときにプログラミングに高速チャネルを提供する可能性があります.ここでmap内部のデータの組織について言えば、map内部には赤と黒の木(厳密な意味ではないバランスの二叉木)が建てられています.この木はデータを自動的にソートする機能を持っているので、map内部のすべてのデータは秩序正しく、後で秩序の良いところを見ることができます.次に、一対一のデータマッピングとは何かを例示する.例えば、クラスでは、各学生の学号と彼の名前には1つ1つのマッピングの関係があり、このモデルはmapで簡単に記述される可能性があり、明らかに学号はintで記述され、名前は文字列で記述されている(この文章ではchar*で文字列を記述するのではなく、STLでstringで記述されている).以下にmap記述コードを示す.
map<int, string> mapStudent;

1.mapのコンストラクション関数mapは6つのコンストラクション関数を提供しています.これはメモリディスペンサに関連しています.表にはありません.以下ではmapのコンストラクション方法に触れます.ここでは、通常、次の方法でmapを構築します.
Map<int, string> mapStudent;

2.データの挿入はmapコンテナを構築した後、私たちは中にデータを挿入することができます.ここでは3つのデータを挿入する方法について説明します.1つ目はinsert関数でpairデータを挿入することです.
<span style="font-family:SimSun;">#</span>include <map>
#include <string>
#include <iostream>
using namespace std;

int main()
{

	map<int, string> mapStudent;
	mapStudent.insert(pair<int, string>(1, "student_one"));
	mapStudent.insert(pair<int, string>(2, "student_two"));
	mapStudent.insert(pair<int, string>(3, "student_three"));
	map<int, string>::iterator iter;
	for(iter = mapStudent.begin(); iter != mapStudent.end(); iter++)
	{
		cout<<iter->first<<""<<iter->second<<endl;
	}
}

2つ目:insert関数でvalue_を挿入するtypeデータ、次に例を挙げて説明する
#include <map>
#include <string>
#include <iostream>
using namespace std;

int main()
{
	map<int, string> mapStudent;
	mapStudent.insert(map<int, string>::value_type (1, "student_one"));
	mapStudent.insert(map<int, string>::value_type (2, "student_two"));
	mapStudent.insert(map<int, string>::value_type (3, "student_three"));
	map<int, string>::iterator iter;
	for(iter = mapStudent.begin(); iter != mapStudent.end(); iter++)
	{
		cout<<iter->first<<""<<iter->second<<endl;
	}
	return 0;
}

3つ目:配列でデータを挿入し、次に例を挙げて説明する
#include <map>
#include <string>
#include <iostream>
using namespace std;

int main()
{
	map<int, string> mapStudent;
	mapStudent[1] = "student_one";
	mapStudent[2] = "student_two";
	mapStudent[3] = "student_three";
	map<int, string>::iterator iter;
	for (iter = mapStudent.begin(); iter != mapStudent.end(); iter++)
	{
		cout<<iter->first<<""<<iter->second<<end;
	}
}

以上の3つの用法は、いずれもデータの挿入を実現することができるが、それらには違いがある:第1種と第2種は効果的に同じであり、insert関数でデータを挿入し、データの挿入に集合の一意性という概念、すなわちmapにこのキーワードがある場合、Insert操作はデータを挿入できません.3つ目は配列で異なり、以前のキーワードに対応した値を上書きできます.
	mapStudent.insert(map<int, string>::value_type (1, "student_one"));
	mapStudent.insert(map<int, string>::value_type (1, "student_two"));

上記の2つの文が実行された後、mapの1というキーワードに対応する値は「student_one」であり、2番目の文は有効ではありません.では、insert文が正常に挿入されたかどうかをどのように知るかについて、pairで挿入に成功したかどうかを得ることができます.
	pair<map<int, string>::iterator, bool> Insert_Pair;
	Insert_Pair = mapStudent.insert(map<int, string>::value_type (1, "student_one"));

私たちはpairの2番目の変数を通じて挿入に成功したかどうかを知っています.その1番目の変数はmapの反復器を返しています.挿入に成功すればInsert_Pair.secondはtrueのはずです.そうでなければfalseです.次に、挿入に成功したかどうかの問題を示す完了コードを示します.
#include <map>
#include <string>
#include <iostream>
using namespace std;

int main()
{
	map<int, string> mapStudent;
	pair<map<int, string>::iterator, bool> Insert_Pair;
	Insert_Pair = mapStudent.insert(pair<int, string>(1, "student_one"));
	if (Insert_Pair.second == true)
	{
		cout<<"Insert Successfully"<<endl;
	}
	else
	{
		cout<<"Insert Failure"<<endl;
	}
	Insert_Pair = mapStudent.insert(pair<int, string>(1, "student_two"));
	if(Insert_Pair.second == true)
	{
		cout<<"Insert Successfully"<<endl;
	}
	else
	{
		cout<<"Insert Failure"<<endl;
	}

	map<int, string>::iterator iter;
	for(iter = mapStudent.begin(); iter != mapStudent.end(); iter++)
	{
		cout<<iter->first<<""<<iter->second<<endl;
	}
}

データオーバーライドに配列を挿入する効果を試してみましょう3.mapのサイズがmapにデータを挿入しています.現在どれだけのデータが挿入されているか、size関数を使って、次のように使えます.
int nSize = mapStudent.size();

4.データの遍歴ここでも3つの方法を提供し、mapを遍歴する第1の方法:順方向反復器を適用し、上の例のプログラムでは第2の方法:逆方向反復器を適用する:
#include <map>
#include <string>
#include <iostream>
using namespace std;

int main()
{
	map<int, string> mapStudent;
	mapStudent.insert(pair<int, string>(1, "student_one"));
	mapStudent.insert(pair<int, string>(2, "student_two"));
	mapStudent.insert(pair<int, string>(3, "student_three"));
	map<int, string>::reverse_iterator iter;
	for (iter = mapStudent.rbegin(); iter != mapStudent.rend(); iter++)
	{
		cout<<iter->first<<""<<iter->second<<endl;
	}
}

3つ目:配列方式で、プログラムの説明は以下の通りです.
#include <map>
#include <string>
#include <iostream>
using namespace std;

int main()
{
	map<int, string> mapStudent;
	mapStudent.insert(pair<int, string>(1, "student_one"));
	mapStudent.insert(pair<int, string>(2, "student_two"));
	mapStudent.insert(pair<int, string>(3, "student_three"));
	int nSize = mapStudent.size();
	for (int nIndex = 0; nIndex < nSize; nIndex++)
	{
		cout<<mapStudent[nIndex]<<end;
	}
}

5.データの検索(このキーワードがmapに現れるかどうかを判定することを含む)ここでは、mapがデータ挿入時に秩序を保証する利点を体得する.1つのデータ(キーワード)がmapに現れるかどうかを判定する方法が多い場合、ここではタイトルはデータの検索ですが、ここではmapの基本的な使い方がたくさん挿入されています.ここでは3つのデータ検索方法を示します.1つ目はcount関数でキーワードが現れるかどうかを判定することです.その欠点はデータの出現位置を特定できないことです.mapの特性のため、1対1のマッピング関係で、count関数の戻り値が2つしかないか、0か、1か、現れる場合を決定します.もちろん1を返します第2種:find関数でデータの出現の位置を位置決めして、それは1つの反復器を返して、データが現れた時、それはデータの所在する位置の反復器を返して、mapの中で探すデータがないならば、それが返す反復器はend関数の帰還する反復器に等しくて、プログラムの説明
#include <map>
#include <string>
#include <iostream>
using namespace std;

int main()
{
	map<int, string> mapStudent;
	mapStudent.insert(pair<int, string>(1, "student_one"));
	mapStudent.insert(pair<int, string>(2, "student_two"));
	mapStudent.insert(pair<int, string>(3, "student_three"));
	map<int, string>::iterator iter;
	iter = mapStudent.find(1);
	if (iter != mapStudent.end())
	{
		cout<<"Find, the value is"<<iter->second<<endl;
	}
	else
	{
		cout<<"Do not Find"<<endl;
	}

}

iteratorlower_bound(const key_type&key):キー値>=keyの最初の要素を指す反復器を返します.iterator upper_bound(const key_type&key):キー値>keyの最初の要素を指す反復器を返します.★降順に並ぶ容器:iteratorlower_bound(const key_type&key):キー値<=keyの最初の要素を指す反復器を返します.iterator upper_bound(const key_type&key):キー値第三に、この方法はデータが現れたかどうかを判定するために使用され、愚かに見える.
昇順に並べられたコンテナ:
#include <map>
#include <string>
#include <iostream>
using namespace std;

int main()
{
	map<int, string> mapStudent;
	mapStudent[1] = "student_one";
	mapStudent[3] = "student_three";
	mapStudent[5] = "student_five";
	map<int, string>::iterator iter;
	iter = mapStudent.lower_bound(2);
	{
		//       3    
		cout<<iter->second<<endl;
	}

	iter = mapStudent.lower_bound(3);
	{
		//       3    
		cout<<iter->second<<endl;
	}

	iter = mapStudent.upper_bound(2);
	{
		//       3    
		cout<<iter->second<<endl;
	}

	iter = mapStudent.upper_bound(3);
	{
		//       5    
		cout<<iter->second<<endl;
	}

	pair<map<int, string>::iterator, map<int, string>::iterator> mapPair;
	mapPair = mapStudent.equal_range(2);

	if (mapPair.first == mapPair.second)
	{
		cout<<"Do not Find"<<endl;
	}
	else
	{
		cout<<"Find"<<endl;
	}
	mapPair = mapStudent.equal_range(3);
	if (mapPair.first == mapPair.second)
	{
		cout<<"Do not Find"<<endl;
	}
	else
	{
		cout<<"Find"<<endl;
	}
}

6.データのクリアとクリアクリアmapのデータはclear()関数で、mapにempty()関数を使用できるデータがあるかどうかを判定し、trueを返すと空mapであることを示す.7.データの削除ここではerase関数を使用し、3つの再ロードされた関数があり、以下に例でそれらの使い方を詳しく説明する
#include <map>
#include <string>
#include <iostream>
using namespace std;

int main()
{
	map<int, string> mapStudent;
	mapStudent[1] = "student_one";
	mapStudent[3] = "student_three";
	mapStudent[5] = "student_five";
	//     1,      
	map<int, string>::iterator iter;
	iter = mapStudent.find(1);
	mapStudent.erase(iter);

	//     1,      
	int n = mapStudent.erase(1);//        1,    0

	//    ,     
	//       map  
	mapStudent.erase(mapStudent.begin(), mapStudent.end());
	//         ,  STL   ,              
}

8.その他の関数の使い方ここにはswap,key_があります.comp,value_comp,get_Allocatorなどの関数は、プログラミングに多く使われていないと感じていますが、少しは表に出さないので、興味があれば自分で研究することができます.9.ソートここでは少し深い使い方を話しています.ソートの問題は、STLではデフォルトでは小さい番号でソートされています.以上のコードはソートに問題はありません.上のキーワードはint型なので、それ自体は小さい番号の演算をサポートして、いくつかの特殊な情況、例えばキーワードは1つの構造体で、並べ替えに関連して問題が発生することができて、それは小さい番号の操作がないため、insertなどの関数はコンパイルする時過ぎられないで、以下は2つの方法を提供してこの問題を解決します第1種:小さい番号のリロード、プログラムの例
<span style="font-family:SimSun;">#</span>include <map>
#include <string>
using namespace std;

typedef struct tagStudentInfo
{
	int nID;
	string strName;
}StudentInfo, *PStudentInfo; //    

int main()
{
	int nSize;

	//         
	map<StudentInfo, int>mapStudent;
	map<StudentInfo, int>::iterator iter;
	StudentInfo studentInfo;
	studentInfo.nID = 1;
	studentInfo.strName = "student_one";
	mapStudent.insert(pair<StudentInfo, int>(studentInfo, 90));
	studentInfo.nID = 2;
	studentInfo.strName = "student_two";
	mapStudent.insert(pair<StudentInfo, int>(studentInfo, 80));
	for (iter=mapStudent.begin(); iter!=mapStudent.end(); iter++)
		cout<<iter->first.nID<<endl<<iter->first.strName<<endl<<iter->second<<endl;
}

以上のプログラムはコンパイルできません.番号より小さいものをリロードすればOKです.以下のようにします.
typedef struct tagStudentInfo
{
	int nID;
	string strName;
	bool operator < (tagStudentInfo const& _A) const
	{
		//          , nID  ,  nID    , strName  
		if(nID < _A.nID) return true;
		if(nID == _A.nID) return strName.compare(_A.strName) < 0;
		return false;
	}
}StudentInfo, *PStudentInfo; //    

2つ目:シミュレーション関数の応用、この時構造体の中で直接的な小さい号の重荷がなくて、3番目のソートパラメータをプラスしました
#include <map>
#include <string>
using namespace std;

typedef struct tagStudentInfo
{
	int nID;
	string strName;
}StudentInfo, *PStudentInfo; //    
class sort
{
public:
	bool operator() (StudentInfo const &_A, StudentInfo const &_B) const
	{
		if(_A.nID < _B.nID) return true;
		if(_A.nID == _B.nID) return _A.strName.compare(_B.strName) < 0;
		return false;
	}
};

int main()
{
	//         ,     sort
	map<StudentInfo, int, sort>mapStudent;
	StudentInfo studentInfo;
	studentInfo.nID = 1;
	studentInfo.strName = "student_one";
	mapStudent.insert(pair<StudentInfo, int>(studentInfo, 90));
	studentInfo.nID = 2;
	studentInfo.strName = "student_two";
	mapStudent.insert(pair<StudentInfo, int>(studentInfo, 80));
}

10.STLは統一された全体であるため、mapの多くの使い方はSTLの他のものと結合されています.例えば、ソートでは、デフォルトではless<>より小さい番号が使用されます.また、mapでは内部秩序が保たれているため、赤黒ツリーで保証されているため、多くの関数が実行する時間の複雑さはlog 2 Nであり、map関数で実現できる機能であれば、STL Algorithmでもこの機能を完成することができ、mapで関数を持参することを提案し、効率が高い.次に、mapの空間的な特性を説明します.そうしないと、mapの各データは赤と黒の木の上のノードに対応しています.このノードはあなたのデータを保存しないとき、16バイトを占めています.親ノードのポインタ、左右の子供のポインタ、そして列挙値があります.(赤と黒を示す、バランスツリーのバランス係数に相当)メモリがかかります