Explicação detalhada do contêiner do conjunto C++ STL

O conceito de container set/multiset

Recursos: Todos os elementos serão classificados automaticamente quando inseridos.
Essência: conjunto/multiconjunto é um contêiner associativo e a estrutura subjacente é implementada com uma árvore binária

A diferença entre set e multiset:
set não permite elementos repetidos no container
multiset permite elementos repetidos no container

Observação: os arquivos de cabeçalho precisam ser incluídos ao usar contêineres de conjunto ou multiconjunto

#include<set>

1. A construção e atribuição do conjunto

Construção:
set<T> st;//Construção padrão
set(const set& st);//Copiar construção
Atribuição:
set& operator=(const set& st);Operador de atribuição de sobrecarga

Antes de testar, primeiro criamos uma função de impressão, que é frequentemente usada em testes

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

Caso de teste:

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

Resultado dos testes:
insira a descrição da imagem aqui

2. definir tamanho e troca

Protótipo da função:
size();//Retorna o número de elementos no contêiner
empty();//Julga se o contêiner está vazio, retorna 1 se estiver vazio, caso contrário, retorna 0
swap();//Troca dois contêineres

Caso de teste:

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

Resultado dos testes:
insira a descrição da imagem aqui

3. definir inserção e exclusão

Protótipo da função:
insert();//Inserir um elemento no contêiner
erase(pos);//Excluir o elemento apontado pelo iterador pos, retornar o iterador do próximo elemento
erase(elem);//Excluir o elemento cujo valor é elem no contêiner
erase(begin,end);//Excluir o intervalo do iterador é [ beg,end) Todos os elementos no container retornam um iterador para o próximo elemento
clear();//Esvazia todos os elementos no container

Caso de teste:

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

Resultado dos testes:
insira a descrição da imagem aqui

4. Defina a pesquisa e as estatísticas

Protótipo da função:
find(elem);//Encontre a posição do elem no container, se houver um iterador para elem retornar o elemento, return set.end() se não houver elem; // O
count(elem);número de elementos elem no container a serem contado, o número de elementos no contêiner definido pode ser apenas 0 ou 1, o contêiner multiconjunto pode ser maior que 1

Caso de teste:

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

Resultado dos testes:
insira a descrição da imagem aqui

5. A diferença entre set e multiset

a diferença:

  • set não permite inserir os mesmos dados, enquanto multiset permite
  • Quando set insere dados, ele retornará o resultado da inserção, indicando se a inserção foi bem-sucedida, e o resultado é recebido pelo par
  • multiset não detectará dados, então os mesmos dados podem ser inseridos

O par de grupos será apresentado em detalhes abaixo, agora use-o primeiro

Caso de teste:

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

Resultado dos testes:
insira a descrição da imagem aqui

6. criação de grupos de pares

O conceito de pares: dados que ocorrem em pares

Duas formas de criar:
pair<T1,T2> p(value1,value2);
pair<T1,T2> p = make_pair(value1,value2);
use:
p.first;//retorna o primeiro tipo de dado do par
p.second;//retorna o segundo tipo de dado do par

Vale ressaltar que o uso do par não requer um arquivo de cabeçalho

Caso de teste:

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

Resultado dos testes:
insira a descrição da imagem aqui

7. defina o agrupamento do contêiner

Já sabemos que ao inserirmos os dados, o container definido irá nos ordenar automaticamente, por padrão, ele é ordenado do menor para o maior, ou seja, em ordem crescente.
Você deve estar se perguntando:

  • Você pode alterar as regras de classificação para classificar em ordem decrescente?
  • Defina uma classe que tenha várias variáveis ​​de membro, então como classificamos por cada membro?

Para os dois casos acima, geralmente introduzimos functors, personalizamos uma regra de classificação e como classificar depende de nós

Caso de teste: classificando tipos de dados integrados

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

Resultado dos testes:
insira a descrição da imagem aqui

Caso de teste: classificação de tipos de dados personalizados

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

Resultado dos testes:
insira a descrição da imagem aqui

Acho que você gosta

Origin blog.csdn.net/qq_52324409/article/details/121280952
Recomendado
Clasificación