Detailed explanation of C++ STL set container

The concept of set/multiset container

Features: All elements will be automatically sorted when inserted
Essence: set/multiset is an associative container, and the underlying structure is implemented with a binary tree

The difference between set and multiset:
set does not allow repeated elements in the container
multiset allows repeated elements in the container

Note: header files need to be included when using set or multiset containers

#include<set>

1. The construction and assignment of set

Construction:
set<T> st;//Default construction
set(const set& st);//Copy construction
Assignment:
set& operator=(const set& st);Overload assignment operator

Before testing, we first create a printout function, which is often used in testing

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

Test Case:

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;         //重载的赋值运算符
}

Test Results:
insert image description here

2.set size and exchange

Function prototype:
size();//Return the number of elements in the container
empty();//Judge whether the container is empty, return 1 if it is empty, otherwise return 0
swap();//Exchange two containers

Test Case:

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);
}

Test Results:
insert image description here

3.set insertion and deletion

Function prototype:
insert();//Insert an element in the container
erase(pos);//Delete the element pointed to by the pos iterator, return the iterator of the next element
erase(elem);//Delete the element whose value is elem in the container
erase(begin,end);//Delete the iterator interval is [beg,end) All elements in the container return an iterator to the next element
clear();//Empty all elements in the container

Test Case:

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);
}

Test Results:
insert image description here

4. Set search and statistics

Function prototype:
find(elem);//Find the position of elem in the container, if there is an iterator for elem to return the element, if there is no
count(elem);elem return set.end(); //The number of elem elements in the container counted, the number of elements in the set container can only be Is 0 or 1, multiset container may be greater than 1

Test Case:

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;
}

Test Results:
insert image description here

5. The difference between set and multiset

the difference:

  • set does not allow inserting the same data, while multiset allows
  • When set inserts data, it will return the insertion result, indicating whether the insertion is successful, and the result is received by the pair
  • multiset will not detect data, so the same data can be inserted

The group pair will be introduced in detail below, now use it first

Test Case:

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;
}

Test Results:
insert image description here

6. pair pair group creation

The concept of pairs: data that occurs in pairs

Two ways to create:
pair<T1,T2> p(value1,value2);
pair<T1,T2> p = make_pair(value1,value2);
use:
p.first;//return the first type of data in the pair
p.second;//return the second type of data in the pair

It is worth mentioning that the use of pair does not require a header file

Test Case:

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;
}

Test Results:
insert image description here

7.set the collation of the container

We already know that when we insert data, the set container will automatically sort us. By default, it is sorted from small to large, that is, in ascending order.
You should be wondering:

  • Can you change the sorting rules to sort in descending order?
  • Define a class that has multiple member variables, so how do we sort by which member?

For the above two cases, we usually introduce functors, customize a sorting rule, and how to sort is up to us

Test case: sorting built-in data types

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;
}

Test Results:
insert image description here

Test Case: Sorting Custom Data Types

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;
	}
}

Test Results:
insert image description here

Guess you like

Origin blog.csdn.net/qq_52324409/article/details/121280952