本文包含set基本概念、set构造和赋值、set大小和交换、set插入和删除、set查找和统计、set和multiset区别、pair对组创建、set容量排序。
简介:
所有元素都会在插入时自动被排序
本质:
set/multiset属于关联式容器,底层结构是用二叉树实现
set和multiset区别:
(1)、set不允许容器中有重复的元素
(2)、multiset允许容器中有重复的元素
功能描述:
创建set容器以及赋值
构造:
(1)、set
默认构造函数
(2)、set(const set &st);
拷贝构造函数
赋值:
set& operator=(const set &st);
重载等号操作符
// set关联式容器构造和赋值
#include // 包含标准输入输出流头文件
using namespace std; // 使用标准命名空间
#include // 使用set栈容器,需包含头文件set
// const对此容器只是只读,不可以修改
void Fun_Print(const set<int>& s) { // 使用引用方式&,传入set类型的形参s
// const_iterator只读迭代器;iterator普通迭代器
for (set<int>::const_iterator it = s.begin(); it != s.end(); it++) {
//*it= 100; // 报错,容器中数据不可修改:表达式必须是可修改的左值
cout << *it << " "; // it是个迭代器类型,本是是个指针,需使用*解引用
}
cout << endl;
}
void test() {
// 1、默认构造,无参构造
set<int> s;
// 插入数据,只有insert方式
s.insert(10);
s.insert(40);
s.insert(70);
// set关联式容器特点:1、所有元素插入时候自动被排序;2、set关联式容器不允许插入重复值
Fun_Print(s); // Fun_Print()遍历容器
// 2、拷贝构造函数
set<int> s1(s);
Fun_Print(s1);
// 3、赋值,重构operator=
set<int> s2;
s2 = s;
Fun_Print(s2);
}
int main() {
test();
system("pause"); // 相当于在本地 Windows 调试器中的:请按任意键继续...;暂停,方便看清楚输出结果
return 0; // 程序正常退出
}
功能描述:
统计set容器大小以及交换set容器
函数原型:
(1)、empty();
判断容器是否为空
(2)、size();
返回容器中元素的数目
(3)、swap(st);
交换两个集合容器
// set关联式容器大小和交换
#include // 包含标准输入输出流头文件
using namespace std; // 使用标准命名空间
#include // 使用set栈容器,需包含头文件set
// const对此容器只是只读,不可以修改
void Fun_Print(const set<int>& s) { // 使用引用方式&,传入set类型的形参s
// const_iterator只读迭代器;iterator普通迭代器
for (set<int>::const_iterator it = s.begin(); it != s.end(); it++) {
//*it= 100; // 报错,容器中数据不可修改:表达式必须是可修改的左值
cout << *it << " "; // it是个迭代器类型,本是是个指针,需使用*解引用
}
cout << endl;
}
void test() {
// 创建set容器对象,并且通过模板参数指定容器中存放的数据的类型
set<int> s;
set<int> s1;
// 插入数据,只有insert方式
s.insert(10);
s.insert(40);
s.insert(70);
s1.insert(300);
s1.insert(200);
s1.insert(800);
Fun_Print(s); // 10 40 70
Fun_Print(s1); // 300 200 800
// 1、empty()判断容器是否为空,为空返回真
if (s.empty()) {
cout << "s容器为空!" << endl;
}
else {
cout << "s容器不为空!" << endl;
// 2、size()返回容器的个数
cout << "s容器的个数为:" << s.size() << endl; // 3
}
// 3、swap()交换两个容器中的数据元素
s1.swap(s);
Fun_Print(s); // 300 200 800
Fun_Print(s1); // 10 40 70
}
int main() {
test();
system("pause"); // 相当于在本地 Windows 调试器中的:请按任意键继续...;暂停,方便看清楚输出结果
return 0; // 程序正常退出
}
功能描述:
set容器进行插入数据和删除数据
函数原型:
(1)、insert(elem);
在容器中插入元素
(2)、erase(pos);
删除pos迭代器所指的元素,返回下一个元素的迭代器
(3)、erase(elem);
删除容器中值为elem的元素
(4)、erase(beg, end);
删除区间[beg,end)的所有元素 ,返回下一个元素的迭代器
(5)、clear();
清除所有元素
// set关联式容器插入和删除
#include // 包含标准输入输出流头文件
using namespace std; // 使用标准命名空间
#include // 使用set栈容器,需包含头文件set
// const对此容器只是只读,不可以修改
void Fun_Print(const set<int>& s) { // 使用引用方式&,传入set类型的形参s
// const_iterator只读迭代器;iterator普通迭代器
for (set<int>::const_iterator it = s.begin(); it != s.end(); it++) {
//*it= 100; // 报错,容器中数据不可修改:表达式必须是可修改的左值
cout << *it << " "; // it是个迭代器类型,本是是个指针,需使用*解引用
}
cout << endl;
}
void test() {
// 创建set容器对象,并且通过模板参数指定容器中存放的数据的类型
set<int> s;
// 1、insert()在容器中插入数据;set容器默认排序规则为从小到大
s.insert(10);
s.insert(40);
s.insert(70);
s.insert(50);
s.insert(80);
Fun_Print(s); // 10 40 50 70 80
// 2、erase()删除s容器开始迭代器处的数据元素
s.erase(s.begin());
Fun_Print(s); // 40 50 70 80
// 3、erase()删除s容器中值为50的数据元素
s.erase(50);
Fun_Print(s); // 40 70 80
// 4、erase()删除s容器开始迭代器到结束迭代器中的数据元素
s.erase(s.begin(), s.end());
Fun_Print(s); //
// 5、clear()清空容器中所有的数据元素
s.clear();
Fun_Print(s); //
}
int main() {
test();
system("pause"); // 相当于在本地 Windows 调试器中的:请按任意键继续...;暂停,方便看清楚输出结果
return 0; // 程序正常退出
}
功能描述:
对set容器进行查找数据以及统计数据
函数原型:
(1)、find(key);
查找key是否存在,若存在,返回该键的元素的迭代器;若不存在,返回set.end()
(2)、count(key);
统计key的元素个数 (0或1)
// set关联式容器查找和统计
#include // 包含标准输入输出流头文件
using namespace std; // 使用标准命名空间
#include // 使用set栈容器,需包含头文件set
// const对此容器只是只读,不可以修改
void Fun_Print(const set<int>& s) { // 使用引用方式&,传入set类型的形参s
// const_iterator只读迭代器;iterator普通迭代器
for (set<int>::const_iterator it = s.begin(); it != s.end(); it++) {
//*it= 100; // 报错,容器中数据不可修改:表达式必须是可修改的左值
cout << *it << " "; // it是个迭代器类型,本是是个指针,需使用*解引用
}
cout << endl;
}
void test() {
// 创建set容器对象,并且通过模板参数指定容器中存放的数据的类型
set<int> s;
// 在容器中插入数据;set容器默认排序规则为从小到大
s.insert(10);
s.insert(40);
s.insert(70);
s.insert(50);
s.insert(80);
// 1、find()查找s容器是否存在“50”这个数据元素
set<int>::iterator pos = s.find(50); // 返回迭代器,使用set::iterator迭代器pos进行接收
if (pos == s.end()) {
cout << "未找到元素" << endl;
}
else {
cout << "找到了元素 : " << *pos << endl; // 找到了元素 : 50;使用*解出这个迭代器的值
}
// 2、count()统计s容器中“50”数据元素的个数
int num = s.count(50);
cout << "num = " << num << endl; // num = 1
}
int main() {
test();
system("pause"); // 相当于在本地 Windows 调试器中的:请按任意键继续...;暂停,方便看清楚输出结果
return 0; // 程序正常退出
}
学习目标:
掌握set和multiset的区别
区别:
(1)、set插入数据的同时会返回插入结果,表示插入是否成功
(2)、set不可以插入重复数据,而multiset可以
(3)、multiset不会检测数据,因此可以插入重复数据
// set关联式容器和multiset关联式容器区别
#include // 包含标准输入输出流头文件
using namespace std; // 使用标准命名空间
#include // 使用set栈容器,需包含头文件set
void test() {
// 创建set容器对象,并且通过模板参数指定容器中存放的数据的类型
set<int> s;
// 1、set插入数据的同时会返回插入结果,表示插入是否成功;返回pair对组
pair<set<int>::iterator, bool> res = s.insert(10); // pair对组,成对出现的一组数据;set::iterator代表插入元素的位置;bool代表插入成功还是失败
if (res.second) { // res.second取res的second第二个数据(bool值)
cout << "第一次插入成功!" << endl; // 第一次插入成功!
}
else {
cout << "第一次插入失败!" << endl;
}
// 2、set不可以插入重复数据,插入重复的10
res = s.insert(10);
if (res.second) {
cout << "第二次插入成功!" << endl;
}
else {
cout << "第二次插入失败!" << endl; // 第二次插入失败!
}
// 创建multiset容器对象,并且通过模板参数指定容器中存放的数据的类型
multiset<int> ms;
// 3、multiset不会检测数据,因此可以插入重复数据
ms.insert(10);
ms.insert(10); // 允许插入重复值
for (multiset<int>::iterator it = ms.begin(); it != ms.end(); it++) {
cout << *it << " "; // 10 10
}
cout << endl;
}
int main() {
test();
system("pause"); // 相当于在本地 Windows 调试器中的:请按任意键继续...;暂停,方便看清楚输出结果
return 0; // 程序正常退出
}
功能描述:
成对出现的数据,利用对组可以返回两个数据
两种创建方式:
(1)、pair
(2)、pair
// pair对组创建
#include // 包含标准输入输出流头文件
using namespace std; // 使用标准命名空间
void test() {
// 1、pair p ( value1, value2 )
pair<string, int> p(string("张三"), 18);
cout << "姓名: " << p.first << " 年龄: " << p.second << endl;
// 2、pair p = make_pair( value1, value2 )
pair<string, int> p2 = make_pair("李四", 40);
cout << "姓名: " << p2.first << " 年龄: " << p2.second << endl;
}
int main() {
test();
system("pause"); // 相当于在本地 Windows 调试器中的:请按任意键继续...;暂停,方便看清楚输出结果
return 0; // 程序正常退出
}
学习目标:
set容器默认排序规则为从小到大,掌握如何改变排序规则
主要技术点:
利用仿函数,可以改变排序规则 仿函数:重载了函数调用运算符“()”
示例一 set存放内置数据类型
// set关联式容器排序:内置数据类型
#include // 包含标准输入输出流头文件
using namespace std; // 使用标准命名空间
#include // 使用set栈容器,需包含头文件set
// Fun_Compare仿函数,指定排序类型,从小到大
class Fun_Compare
{
public:
bool operator()(int v1, int v2) const { // 重载(),返回bool,底层还是需要对两个数进行判断对比
return v1 > v2;
}
};
void test() {
// 创建set容器对象,并且通过模板参数指定容器中存放的数据的类型
set<int> s;
// 在容器中插入数据;set容器默认排序规则为从小到大
s.insert(10);
s.insert(40);
s.insert(70);
s.insert(50);
s.insert(80);
// 默认从小到大
for (set<int>::iterator it = s.begin(); it != s.end(); it++) {
cout << *it << " "; // 10 20 30 40 50
}
cout << endl;
// 指定排序规则:从大到小
// Fun_Compare类型,<>模板内都得放数据类型;仿函数Fun_Compare本质上是一个类型;会按照仿函数Fun_Compare的排序规则进行排序
set<int, Fun_Compare> s1; // 插入时就按从小到大给排序好了;如要修改排序规则,不能再插入后指定排序规则;而是要在指定容器时,就指定排序规则,插入前指定
s1.insert(10);
s1.insert(40);
s1.insert(70);
s1.insert(50);
s1.insert(80);
// 遍历set关联式容器
for (set<int, Fun_Compare>::iterator it = s1.begin(); it != s1.end(); it++) {
cout << *it << " ";
}
cout << endl;
}
int main() {
test();
system("pause"); // 相当于在本地 Windows 调试器中的:请按任意键继续...;暂停,方便看清楚输出结果
return 0; // 程序正常退出
}
// set关联式容器排序:自定义数据类型
#include // 包含标准输入输出流头文件
using namespace std; // 使用标准命名空间
#include // 使用set栈容器,需包含头文件set
// 创建一个Person类
class Person
{
public:
Person(string name, int age) // 构造函数,初始值
{
this->m_Name = name;
this->m_Age = age;
}
string m_Name; // 姓名
int m_Age; // 年龄
};
// Fun_Compare仿函数,指定排序类型,从小到大
class Fun_Compare
{
public:
//bool operator()(const Person& p1, const Person &p2) const // const限定,不可修改;使用引号&,防止拷贝构造(浅拷贝)
bool operator()(const Person& p1, const Person& p2) const // const限定,不可修改;使用引号&,防止拷贝构造(浅拷贝)
{
// 按照年龄进行排序 降序
return p1.m_Age > p2.m_Age;
}
};
void test() {
// 创建set容器对象,并且通过模板参数指定容器中存放的数据的类型
set<Person, Fun_Compare> s; // 指定排序顺序
Person p1("张三", 18);
Person p2("李四", 40);
Person p3("王五", 55);
Person p4("赵六", 66);
// 在容器中插入数据
s.insert(p1); // 如果未自定义排序规则Fun_Compare,会报错,编译器插入数据时不知道如何进行从小到大排序
s.insert(p2);
s.insert(p3);
s.insert(p4);
// 遍历set关联式容器
for (set<Person, Fun_Compare>::iterator it = s.begin(); it != s.end(); it++)
{
cout << "姓名: " << it->m_Name << " 年龄: " << it->m_Age << endl;
}
}
int main() {
test();
system("pause"); // 相当于在本地 Windows 调试器中的:请按任意键继续...;暂停,方便看清楚输出结果
return 0; // 程序正常退出
}
(1)、set 容器插入数据时用insert;
(2)、set 容器插入数据的数据会自动排序;
(3)、set 统计大小 — size;
(4)、set 判断是否为空 — empty;
(5)、set 交换容器 — swap;
(6)、set 插入 — insert;
(7)、set 删除 — erase;
(8)、set 清空 — clear;
(9)、set 查找 — find (返回的是迭代器);
(10)、set 统计 — count (对于set,结果为0或者1);
(11)、如果不允许插入重复数据可以利用set;
(12)、如果需要插入重复数据利用multiset;
(13)、两种方式都可以创建对组,记住一种即可;
(14)、利用仿函数可以指定set容器的排序规则;
(15)、对于自定义数据类型,set必须指定排序规则才可以插入数据。