目次
連想コンテナー (関連付けられたコンテナー)、要素の位置は特定の並べ替え基準に依存し、挿入順序とは関係ありません
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;
}
}