c++STL の連想コンテナー

目次

セットコンテナ

セットのデフォルトコンストラクタ

挿入と反復子を設定する

セット コレクションの要素を並べ替える

セット コレクションの初期化と走査

小さいものから大きいものまで (デフォルト)

 大きいものから小さいものまで

ファンクタ 

ルックアップの設定

ペアの使用

multiset容器 

マップおよびマルチマップ コンテナー 

マップの挿入と反復子

マップサイズ

マップの削除

地図検索


連想コンテナー (関連付けられたコンテナー)、要素の位置は特定の並べ替え基準に依存し、挿入順序とは関係ありません

c++STL には、主に set、multiset、map、multimap があります。

セットコンテナ

  • set はコレクション コンテナーであり、そこに含まれる要素は一意であり、コレクション内の要素は特定の順序で配置されます。要素の挿入処理は、ソート規則に従って挿入されるため、挿入位置は指定できません。
  • セットは、平衡二分木に属する赤黒木バリアントのデータ構造を使用して実装されます。挿入と削除のベクトルよりも高速です。
  • set は要素に直接アクセスできません。(at.(pos) および [] 演算子は使用できません)。

セットのデフォルトコンストラクタ

set<int> setInt; //int を格納するセット コンテナ。

set<float> setFloat; //float を格納するセット コンテナ。

set<string> setString; //文字列を格納するセット コンテナ。

multiset<int> mulsetInt; //int を格納するマルチ セット コンテナ。

multi set<float> multisetFloat; //float を格納するマルチ セット コンテナ。

multi set<string> multisetString; //文字列を格納するマルチ セット コンテナ。

挿入と反復子を設定する

  • set.insert(elem); //コンテナに要素を挿入します。
  • set.begin(); //コンテナ内の最初のデータの反復子を返します。
  • set.end(); //コンテナ内の最後のデータの後のイテレータを返します。
  • set.rbegin(); //コンテナ内の最後の要素へのイテレータを返します。
  • set.rend(); //コンテナ内の最後の要素の後ろにあるイテレータを返します。

セット コレクションの要素を並べ替える

  • set<int,less<int> > setIntA; //コンテナは要素を昇順に並べます。
  • set<int,greater<int>> setIntB; //コンテナは要素を降順に並べます。
  • set<int> は set<int,less<int>> と同等です。
  • less<int> と greater<int> の int は他の型に変更できます。その型は、セットに含まれるデータ型と一致している必要があります。

セット コレクションの初期化と走査

小さいものから大きいものまで (デフォルト)

//集合 元素唯一 自动排序 不能按照[]方式插入元素
//默认情况下是从小到大
void main91()
{
	set<int> set1;
	for (int i = 0; i < 5; i++)
	{
		int tmp = rand();
		set1.insert(tmp);
	}
	set1.insert(100);
	set1.insert(100);
	set1.insert(100);
	for (set<int>::iterator it = set1.begin(); it != set1.end(); it++)
	{
		cout << *it << " ";
	}
	cout << endl;
	while (!set1.empty())
	{
		set<int>::iterator it = set1.begin();
		cout << *it << " ";
		set1.erase(set1.begin());
	}
}

 大きいものから小さいものまで

void main92()
{
	set<int,greater<int>> set1;
	for (int i = 0; i < 5; i++)
	{
		int tmp = rand();
		set1.insert(tmp);
	}
	set1.insert(100);
	set1.insert(100);
	set1.insert(100);
	for (set<int,greater<int>>::iterator it = set1.begin(); it != set1.end(); it++)
	{
		cout << *it << " ";
	}
	cout << endl;

}

ファンクタ 

複雑なデータ型セットのコレクションがユーザー定義によってソートされる場合、ファンクターのメカニズムが主に使用されます。

//仿函数
struct FuncStudent
{
	bool operator()(const Student& left, const Student& right) const
	{
		if (left.m_age < right.m_age)
		{
			return true;
		}
		else
		{
			return false;
		}
	}
};

void main93()
{
	set<Student, FuncStudent> set1;
	Student s1("s1", 32);
	Student s2("s2", 22);
	Student s3("s3", 16);
	Student s4("s4", 55);
	Student s5("s5", 32);

	set1.insert(s1);
	set1.insert(s2);
	set1.insert(s3);
	set1.insert(s4);
	set1.insert(s5);//两个一样的值
	//如何知道插入的结果

	//遍历
	for (set<Student, FuncStudent>::iterator it = set1.begin(); it != set1.end(); it++)
	{
		cout << it->m_age << "\t" << it->m_name << endl;
	}
}

ルックアップの設定

  • set.find(elem); // elem 要素を見つけて、その elem 要素を指す反復子を返します。
  • set.count(elem); //コンテナー内で値が elem である要素の数を返します。セットの場合は、0 または 1 のいずれかです。マルチセットの場合、値は 1 より大きい場合があります。
  • set.lower_bound(elem); //最初の >=elem 要素の反復子を返します。
  • set.upper_bound(elem); // 最初の >elem 要素への反復子を返します。
  • set.equal_range(elem); //コンテナー内の elem に等しい上限と下限の 2 つの反復子を返します。上限は閉区間で、下限は [beg,end) などの開区間です。

ペアの使用

  • ペアはペアに変換され、2 つの値を単位と見なすことができます。
  • ペア <T1, T2> に格納される 2 つの値の型は異なる場合があります。たとえば、T1 は int で、T2 は float です。T1、T2 はカスタム タイプにすることもできます。
  • pair.first は、T1 型のペアの最初の値です。
  • pair.second は、ペアの 2 番目の値で、T2 型です。

set<int> setInt;

... // 要素 1、3、5、7、9 を setInt コンテナに挿入します

pair< set<int>::iterator , set<int>::iterator > pairIt = setInt.equal_range(5);

set<int>::iterator itBeg = pairIt.first;

set<int>::iterator itEnd = pairIt.second;

// この時点で *itBeg==5 および *itEnd == 7

//如何判断insert的返回值
void main94()
{
	set<Student, FuncStudent> set1;
	Student s1("s1", 32);
	Student s2("s2", 22);
	Student s3("s3", 16);
	Student s4("s4", 55);
	Student s5("s5", 32);

	pair<set<Student, FuncStudent>::iterator, bool> pair1;
	pair1 = set1.insert(s1);
	if (pair1.second)
	{
		cout << "插入s1成功" << endl;
	}
	else
	{
		cout << "插入s1失败" << endl;
	}
	set1.insert(s2);
	set1.insert(s3);
	set1.insert(s4);
	pair1 = set1.insert(s5);//两个一样的值
	if (pair1.second)
	{
		cout << "插入s5成功" << endl;
	}
	else
	{
		cout << "插入s5失败" << endl;
	}
		//遍历
	for (set<Student, FuncStudent>::iterator it = set1.begin(); it != set1.end(); it++)
	{
		cout << it->m_age << "\t" << it->m_name << endl;
	}
}

multiset容器 

  • multiset と set の違い: set は一意のキー値をサポートし、各要素の値は 1 回しか表示できませんが、multiset では同じ値を複数回表示できます。
  • このタイプのコンテナーは自動的にソートされるため、セットまたはマルチセット コンテナー内の要素の値を直接変更することはできません。要素の値を変更する場合は、最初に元の要素を削除してから、新しい要素を挿入する必要があります。
void main101()
{
	multiset<int> set1;
	int tmp;

	cout << "请输入multiset集合的值:";
	scanf("%d", &tmp);
	while (tmp != 0)
	{
		set1.insert(tmp);
		cout << "请输入multiset集合的值:";
		scanf("%d", &tmp);
	}

	//遍历
	for (multiset<int>::iterator it = set1.begin(); it != set1.end(); it++)
	{
		cout << *it << " ";
	}
	cout << endl;

	while (!set1.empty())
	{
		multiset<int>::iterator it = set1.begin();
		cout << *it << " ";
		set1.erase(set1.begin());
	}
}

マップおよびマルチマップ コンテナー 

  • マップは標準の連想コンテナーであり、マップは一連のキーと値のペア、つまり (キー、値) のペアです。キーベースの高速検索機能を提供します。
  • マップのキー値は一意です。コレクション内の要素は、特定の順序で配置されます。要素の挿入処理は、ソート規則に従って挿入されるため、挿入位置は指定できません。
  • map の特定の実装は、赤黒木のバランスのとれた二分木バリアントのデータ構造を採用しています。挿入と削除のベクトルよりも高速です。
  • マップは、キーに対応する値に直接アクセスでき、map[key]=value などの [] 演算子をサポートします。
  • multimap と map の違い: map は一意のキー値をサポートし、各キーは 1 回しか表示されませんが、multimap では同じキーが複数回表示されます。multimap は [] 演算子をサポートしていません。

マップの挿入と反復子

  • map.insert(...); //要素をコンテナに挿入し、pair<iterator,bool> を返します
  • マップに要素を挿入するには、次の 3 つの方法があります。

map<int, string> mapStu; とします。

  • 1.オブジェクトをペアで挿入

mapStu.insert( pair<int,string>(3,"Xiao Zhang") );

  • 2. オブジェクトをペアで挿入する

mapStu.inset(make_pair(-1, "プリンシパル-1"));

  • 3. value_type によるオブジェクトの挿入

mapStu.insert( map<int,string>::value_type(1,"小李") );

  • 4.配列を介して値を挿入する

mapStu[3] = "小劉";

mapStu[5] = "小王";

  • 最初の 3 つのメソッドは insert() メソッドを使用し、このメソッドの戻り値は pair<iterator, bool> です。
  • 4 番目の方法は非常に直感的ですが、パフォーマンスの問題があります。3 を挿入する場合は、まず mapStu で主キーが 3 であるアイテムを検索し、見つからない場合は、キーが 3 で値が初期化値であるペアを mapStu に挿入し、値を「Xiao Liu」に変更します。キー 3 が既に存在することが判明した場合は、このキーに対応する値を変更します。
  • string strName = mapStu[2]; // フェッチ操作または挿入操作
  • キー 2 が mapStu に存在する場合のみ、正しいフェッチ操作になります。それ以外の場合は、インスタンスが自動的に挿入されます。キーは 2 で、値は初期化値です。

マップサイズ

  • map.size(); //コンテナ内の要素数を返す
  • map.empty();//コンテナが空かどうかを判断する

マップの削除

  • map.clear(); //すべての要素を削除
  • map.erase(pos); // pos イテレータが指す要素を削除し、次の要素のイテレータを返します。
  • map.erase(beg,end); //区間 [beg,end) 内のすべての要素を削除し、次の要素の反復子を返します。
  • map.erase(keyElem); //コンテナ内のキーが keyElem のペアを削除します。

地図検索

  • map.find(key); キー key が存在するかどうかを調べ、存在する場合はキーの要素の反復子を返し、存在しない場合は map.end(); を返します。
  • map.count(keyElem); //コンテナ内でキーが keyElem であるペアの数を返します。マップの場合は、0 または 1 です。マルチマップの場合、値は 1 より大きい場合があります。
//map的添加/遍历/删除
void main111()
{
	map<int, string> map1;
	
	//方法一
	map1.insert(pair<int, string>(1, "teacher01"));
	map1.insert(pair<int, string>(2, "teacher02"));
	
	//方法二
	map1.insert(make_pair(3, "teacher03"));
	map1.insert(make_pair(4, "teacher04"));

	//方法三
	map1.insert(map<int, string>::value_type(5, "teacher05"));
	map1.insert(map<int, string>::value_type(6, "teacher06"));
	
	//方法四
	map1[7] = "teacher07";
	map1[8] = "teacher08";

	//容器的遍历
	for (map<int, string>::iterator it = map1.begin(); it != map1.end(); it++)
	{
		cout << it->first << "\t" << it->second << endl;
	}
	cout << "遍历结束" << endl;

	//容器的删除
	while (!map1.empty())
	{
		map<int, string>::iterator it = map1.begin();
		cout << it->first << "\t" << it->second << endl;
		map1.erase(it);
	}
}

//插入的四种方法异同
//前三种返回值是pair<iterator,bool>
//前三种方法若key已经存在则报错
//方法四    若key已经存在则覆盖
void main112()
{
	map<int, string> map1;

	//方法一
	pair<map<int, string>::iterator,bool> mypair1 = map1.insert(pair<int, string>(1, "teacher01"));
	map1.insert(pair<int, string>(2, "teacher02"));

	//方法二
	pair<map<int, string>::iterator, bool> mypair3 = map1.insert(make_pair(3, "teacher03"));
	map1.insert(make_pair(4, "teacher04"));

	//方法三
	pair<map<int, string>::iterator, bool> mypair5 = map1.insert(map<int, string>::value_type(5, "teacher05"));
	if (mypair5.second)
	{
		cout << mypair5.first->first << mypair5.first->second << endl;
	}
	else
	{
		cout << "key5 插入失败" << endl;
	}
	pair<map<int, string>::iterator, bool> mypair6 = map1.insert(map<int, string>::value_type(5, "teacher06"));
	if (mypair6.second)
	{
		cout << mypair6.first->first << mypair6.first->second << endl;
	}
	else
	{
		cout << "key5 插入失败" << endl;
	}
	//方法四
	map1[7] = "teacher07";
	map1[7] = "teacher77";

	//容器的遍历
	for (map<int, string>::iterator it = map1.begin(); it != map1.end(); it++)
	{
		cout << it->first << "\t" << it->second << endl;
	}
	cout << "遍历结束" << endl;
}

 

void main113()
{
	map<int, string> map1;

	//方法一
	map1.insert(pair<int, string>(1, "teacher01"));
	map1.insert(pair<int, string>(2, "teacher02"));

	//方法二
	map1.insert(make_pair(3, "teacher03"));
	map1.insert(make_pair(4, "teacher04"));

	//方法三
	map1.insert(map<int, string>::value_type(5, "teacher05"));
	map1.insert(map<int, string>::value_type(6, "teacher06"));

	//方法四
	map1[7] = "teacher07";
	map1[8] = "teacher08";

	//容器的遍历
	for (map<int, string>::iterator it = map1.begin(); it != map1.end(); it++)
	{
		cout << it->first << "\t" << it->second << endl;
	}
	cout << "遍历结束" << endl;

	//map的查找
	map<int, string>::iterator it2 = map1.find(100);
	if (it2 == map1.end())
	{
		cout << "key 100的值不存在" << endl;
	}
	else
	{
		cout << it2->first << "\t" << it2->second << endl;
	}

	//equal_range
	pair<map<int, string>::iterator, map<int, string>::iterator> mypair = map1.equal_range(5);//返回两个迭代器 形成一个pair
	//第一个迭代器>=5的位置
	//第二个迭代器>5的位置
	if (mypair.first == map1.end())
	{
		cout << "第一个迭代器不存在" << endl;
	}
	else
	{
		cout << mypair.first->first << "\t" << mypair.first->second << endl;
	}

	//使用第二个迭代器
	if (mypair.second == map1.end())
	{
		cout << "第一个迭代器不存在" << endl;
	}
	else
	{
		cout << mypair.second->first << "\t" << mypair.second->second << endl;
	}
}

 

 

おすすめ

転載: blog.csdn.net/qq_45526401/article/details/130185018