C++ STLセットコンテナの詳細説明

セット/マルチセットコンテナの概念

特徴: すべての要素は挿入時に自動的にソートされます
本質: set/multiset は連想コンテナーであり、基礎となる構造はバイナリ ツリーで実装されます

セットとマルチセットの違い:
セットではコンテナ内で要素の繰り返しが許可されません。
マルチセットではコンテナ内で要素の繰り返しが許可されます。

注: セットまたはマルチセット コンテナを使用する場合は、ヘッダー ファイルを含める必要があります。

#include<set>

1. セットの構築と代入

構築:
set<T> st;//デフォルトの構築
set(const set& st);//構築のコピー
代入:
set& operator=(const set& st);オーバーロード代入演算子

テストの前に、まずテストでよく使用される出力関数を作成します。

void printSet(const set<int>& st)
{
    
    
	cout << "打印set容器:" ;
	for (set<int>::iterator it = st.begin(); it != st.end(); it++)
	{
    
    
		cout << *it << " ";
	}
	cout << endl;
}

テストケース:

void text()
{
    
    
	set<int> s1;      //默认构造

	//set插入数据只有insert的方式
	s1.insert(20);
	s1.insert(30);
	s1.insert(10);
	//s1.insert(10); //容器中已经有相同的元素,插入失败,但并不报错

	//打印s1,是按升序排序好的顺序打印的
	printSet(s1);

	set<int> s2(s1); //拷贝构造
	set<int> s3;  
	s3 = s1;         //重载的赋值运算符
}

試験結果:
ここに画像の説明を挿入

2.サイズの設定と交換

関数プロトタイプ:
size();//コンテナ内の要素数を返す
empty();//コンテナが空かどうかを判断し、空なら1を返し、空でなければ0を返す
swap();//2つのコンテナを交換する

テストケース:

void text()
{
    
    
	set<int> s1, s2;
	//empty()
	if (s1.empty())  //如果s1为空
	{
    
    
		s1.insert(1);
		s1.insert(5);
		s1.insert(3);
	}
	if (s2.empty())
	{
    
    
		s2.insert(10);
		s2.insert(50);
		s2.insert(30);
		s2.insert(80);
	}
	//size()
	cout << "s1的大小为:" << s1.size() << endl;
	cout << "s2的大小为:" << s2.size() << endl;

	//swap()
	cout << "交换前:" << endl;
	printSet(s1);
	printSet(s2);
	s1.swap(s2);//交换s1和s2
	cout << "交换后:" << endl;
	printSet(s1);
	printSet(s2);
}

試験結果:
ここに画像の説明を挿入

3.セットの挿入と削除

関数プロトタイプ:
insert();//コンテナに要素を挿入
erase(pos);//pos イテレータが指す要素を削除し、次の要素のイテレータを返す
erase(elem);//コンテナ内の値が elem である要素を削除
erase(begin,end);//イテレータの間隔を削除beg,end) コンテナ内のすべての要素は次の要素へのイテレータを返します
clear();//コンテナ内のすべての要素を空にする

テストケース:

void text()
{
    
    
	set<int> s;
	//insert()
	s.insert(10);
	s.insert(8);
	s.insert(15);
	s.insert(2);
	printSet(s);
	//erase()
	s.erase(s.begin());   //删除首个元素,由于set容器插入时已经升序排序好了,此时删除的是最小的元素
	printSet(s);
	s.erase(10);          //删除为10的元素
	printSet(s);

	//清空
	s.clear(); //等价于s.erase(s.begin(),s.end());
	printSet(s);
}

試験結果:
ここに画像の説明を挿入

4. 検索と統計を設定する

関数プロトタイプ:
find(elem);//コンテナ内の elem の位置を検索、要素を返す elem のイテレータがある場合、elem がない場合
count(elem);return set.end(); //コンテナ内の elem 要素の数をカウント、セット コンテナ内の要素の数は 0 または 1 のみです。マルチセット コンテナは 1 より大きい場合があります

テストケース:

void text()
{
    
    
	set<int> s;
	s.insert(5);
	s.insert(3);
	s.insert(4);
	s.insert(2);
	printSet(s);
	//find()
	set<int>::iterator pos = s.find(5);
	if (pos != s.end())
	{
    
    
		cout << "找到元素:" << *pos << endl;
	}
	else cout << "没有该元素" << endl;

	//count()
	cout << "元素5" << "有" << s.count(5) << "个" << endl;
}

試験結果:
ここに画像の説明を挿入

5. セットとマルチセットの違い

違い:

  • set では同じデータの挿入は許可されませんが、multiset では許可されます。
  • set がデータを挿入すると、挿入が成功したかどうかを示す挿入結果が返され、その結果がペアによって受信されます。
  • マルチセットはデータを検出しないため、同じデータを挿入できます

グループペアについては以下で詳しく紹介しますので、最初に使用してください。

テストケース:

void text()
{
    
    
	set<int> s;
	//用pair接收s的插入结果
	pair < set<int>::iterator, bool > ret = s.insert(10);
	if (ret.second)//ret的第二个类型数据,即bool类型,若为真则插入成功
	{
    
    
		cout << "插入成功" << endl;
	}
	else cout << "插入失败" << endl;
	ret = s.insert(10);
	if (ret.second)//ret的第二个类型数据,即bool类型,若为真则插入成功
	{
    
    
		cout << "插入成功" << endl;
	}
	else cout << "插入失败" << endl;

	//multiset可以重复插入相同元素,不检测插入结果
	multiset<int> ms;
	ms.insert(10);
	ms.insert(10);
	ms.insert(10);
	cout << "打印multiset容器:";
	for (multiset<int>::iterator it = ms.begin(); it != ms.end(); it++)
	{
    
    
		cout << *it << " ";
	}
	cout << endl;
}

試験結果:
ここに画像の説明を挿入

6. ペアペアグループ作成

ペアの概念: ペアで発生するデータ

作成する 2 つの方法:
pair<T1,T2> p(value1,value2);
pair<T1,T2> p = make_pair(value1,value2);
使用:
p.first;// ペアの最初のタイプのデータを返す
p.second;// ペアの 2 番目のタイプのデータを返す

ペアの使用にはヘッダー ファイルが必要ないことに注意してください。

テストケース:

void text()
{
    
    
	//创建
	pair<string, int> p1("张三", 25);
	pair<string, int> p2 = make_pair("李四", 30);
	//使用
	cout << "姓名:" << p1.first << " 年龄:" << p1.second << endl;
	cout << "姓名:" << p2.first << " 年龄:" << p2.second << endl;
}

試験結果:
ここに画像の説明を挿入

7.コンテナの照合順序を設定します

データを挿入すると、set コンテナーが自動的に並べ替えを行うことはすでにわかっていますが、デフォルトでは、小さいものから大きいものへ、つまり昇順で並べ替えられます。
あなたはこう疑問に思うはずです:

  • ソートルールを変更して降順にソートすることはできますか?
  • 複数のメンバー変数を持つクラスを定義する場合、どのメンバーでソートすればよいでしょうか?

上記 2 つのケースでは、通常、ファンクターを導入し、並べ替えルールをカスタマイズします。並べ替え方法は私たち次第です。

テスト ケース: 組み込みデータ型の並べ替え

class Mycompare
{
    
    
public:
	bool operator()(int v1,int v2) const //重载() 运算符
	{
    
    
		return v1 > v2;  //指定排序规则,从大到小,也就是降序排序
	}
};
void text1()
{
    
    
	set<int,Mycompare> s1;
	s1.insert(10);
	s1.insert(50);
	s1.insert(30);
	s1.insert(40);
	cout << "打印降序排序的set容器:" << endl;
	for (set<int, Mycompare>::iterator it = s1.begin(); it != s1.end(); it++)
	{
    
    
		cout << *it << " ";
	}
	cout << endl;
}

試験結果:
ここに画像の説明を挿入

テスト ケース: カスタム データ型の並べ替え

class Person
{
    
    
public:
	string m_name;
	int m_age;
	Person(string name, int age) :m_name(name), m_age(age) {
    
     }
};
class Mycompare
{
    
    
public:
	bool operator()(const Person& p1,const Person& p2) const //重载() 运算符
	{
    
    
		return p1.m_age > p2.m_age; 
	}
};
void text1()
{
    
    
	set<Person,Mycompare> s1;
	Person p1("张三", 25);
	Person p2("李四", 20);
	Person p3("王五", 30);
	s1.insert(p1);
	s1.insert(p2);
	s1.insert(p3);
	cout << "按照年龄大小降序排序:" << endl;
	for (set<Person, Mycompare>::iterator it = s1.begin(); it != s1.end(); it++)
	{
    
    
		cout << "姓名:" << (*it).m_name << "  年龄:" << (*it).m_age << endl;
	}
}

試験結果:
ここに画像の説明を挿入

おすすめ

転載: blog.csdn.net/qq_52324409/article/details/121280952