set

简介:所有元素都会在插入时自动排序

本质:​​set​​​ 与 ​​multiset​​ 属于关联式容器,底层结构是用二叉树实现的

set 构造器与赋值

【函数原型】:

- set<T> st; //默认构造函数

- set(const set &st); //拷贝构造函数

- set operator=(const set &st); //重载等号操作符

【demo】:

#include <iostream>
#include <set>

using namespace std;

void printSet(const set<int> &st)
{
if (st.empty())
{
cout << "set is empty ." << endl;
}
else
{
for (set<int>::const_iterator it = st.begin(); it != st.end(); it++)
{
cout << *it << " ";
}
cout << " , size : " << st.size() << endl;
}
}
void test01()
{
set<int> st;

st.insert(50);
st.insert(30);
st.insert(10);
st.insert(20);
st.insert(40);
printSet(st);

// 拷贝构造
set<int> st2(st);
printSet(st2);

// 赋值
set<int> st3;
st3 = st2;
printSet(st3);
}
int main()
{
test01();
return 0;
}

小结

  • ​set​​ 容器插入元素时用​​insert​
  • ​set​​容器插入元素时会自动排序

set 大小和交换

【函数原型】:

- size(); //返回容器中元素的数目

- empty(); // 判断容器是否为空

- swap(); // 交换两个集合容器

【demo】:

#include <iostream>
#include <set>

using namespace std;

void printSet(const set<int> &st)
{
if (st.empty())
{
cout << "set is empty ." << endl;
}
else
{
for (set<int>::const_iterator it = st.begin(); it != st.end(); it++)
{
cout << *it << " ";
}
cout << " , size : " << st.size() << endl;
}
}
void test01()
{
set<int> st;

st.insert(50);
st.insert(30);
st.insert(10);
st.insert(20);
st.insert(40);

set<int> st2;
st2.insert(100);
st2.insert(300);
st2.insert(400);
st2.insert(200);
st2.insert(500);
cout << "===== before swap ===== " << endl;
cout << "set1 : ";
printSet(st);
cout << "set2 : ";
printSet(st2);

st.swap(st2);
cout << "===== after swap ===== " << endl;
cout << "set1 : ";
printSet(st);
cout << "set2 : ";
printSet(st2);
}
int main()
{
test01();
return 0;
}

set 插入元素和删除元素

【函数原型】:

- insert(elem); // 向容器中插入元素

- clear(); // 清除所有的元素

- erase(pos); // 删除pos迭代器所指的元素,返回下一个元素的迭代器

- erase(begin,end); // 删除[begin,end]区间中的元素,返回下一个元素的迭代器

- erase(elem); // 删除容器中值为elem的元素

【demo】:

#include <iostream>
#include <set>

using namespace std;

void printSet(const set<int> &st)
{
if (st.empty())
{
cout << "set is empty ." << endl;
}
else
{
for (set<int>::const_iterator it = st.begin(); it != st.end(); it++)
{
cout << *it << " ";
}
cout << " , size : " << st.size() << endl;
}
}
void test01()
{
set<int> st;

// 插入元素
st.insert(50);
st.insert(30);
st.insert(10);
st.insert(20);
st.insert(40);
printSet(st);

// 删除元素
st.erase(st.begin());
printSet(st);

// 清空元素
st.clear();
printSet(st);
}
int main()
{
test01();
return 0;
}

set 查找和统计

【函数原型】:

- find(key); // 查找key是否存在,若存在,则返回key对应的迭代器,若不存在,返回set.end();

- count(key); // 统计key的元素个数

【demo】:

#include <iostream>
#include <set>

using namespace std;

void printSet(const set<int> &st)
{
if (st.empty())
{
cout << "set is empty ." << endl;
}
else
{
for (set<int>::const_iterator it = st.begin(); it != st.end(); it++)
{
cout << *it << " ";
}
cout << " , size : " << st.size() << endl;
}
}
void test01()
{
set<int> st;

// 插入元素
st.insert(50);
st.insert(30);
st.insert(10);
st.insert(20);
st.insert(40);
printSet(st);

// 查找元素
set<int>::iterator pos = st.find(30);
if (pos != st.end())
{

cout << "find " << *pos << endl;
}
else
{
cout << "not found . " << endl;
}

// 统计元素个数
int num = st.count(10);
cout << "num = " << num << endl;
}
int main()
{
test01();
return 0;
}

set 与 multiset区别

  • ​set​​ 不可以插入重复数据,而 ​​multiset​​ 可以
  • ​set​​ 插入数据的同时会返回插入结果,表示插入是否成功
  • ​multiset​​ 不会检测数据,可以插入重复数据

【demo】:

#include <iostream>
#include <set>

using namespace std;

// set和multiset的区别
void test01()
{
set<int> s;
pair<set<int>::iterator, bool> ret = s.insert(10);
if (ret.second)
{
cout << "set 第一次插入成功" << endl;
}
else
{
cout << "set 第一次插入失败" << endl;
}

ret = s.insert(10);
if (ret.second)
{
cout << "set 第二次插入成功" << endl;
}
else
{
cout << "set 第二次插入失败" << endl;
}

multiset<int> ms;
ms.insert(10);
ms.insert(10);
cout << "multiset:";
for (multiset<int>::iterator it = ms.begin(); it != ms.end(); it++)
{
cout << *it << " ";
}
cout << endl;
}
int main()
{
test01();
return 0;
}

pair对组创建

成对出现的数据,利用对组可以返回两个数据

【函数原型】:

- pair(type,type) p (value1,value2);

- pair(type,type) p = make_pair(value1,value2);

【demo】:

#include <iostream>
#include <string>

using namespace std;

// 对组创建
void test01()
{
pair<string, int> p(string("张三"), 20);
cout << "姓名:" << p.first << ",年龄:" << p.second << endl;

pair<string, int> p2 = make_pair("李四", 22);
cout << "姓名:" << p2.first << ",年龄:" << p2.second << endl;
}
int main()
{
test01();
return 0;
}

set 容器排序

set 容器默认排序规则为从小到大,利用仿函数,可以改变排序规则

【demo】:

#include <iostream>
#include <set>

using namespace std;

class MyCompare
{
public:
bool operator()(int v1, int v2)
{
return v1 > v2;
}
};

void test01()
{
set<int> s1;
s1.insert(19);
s1.insert(5);
s1.insert(10);
s1.insert(3);

cout << "默认从小到大排序:";
for (set<int>::iterator it = s1.begin(); it != s1.end(); it++)
{
cout << *it << " ";
}
cout << endl;

set<int, MyCompare> s2;
s2.insert(19);
s2.insert(5);
s2.insert(10);
s2.insert(3);
cout << "指定从大大小排序:";

for (set<int, MyCompare>::iterator it = s2.begin(); it != s2.end(); it++)
{
cout << *it << " ";
}
cout << endl;
}
int main()
{
test01();
return 0;
}

set 存放自定义数据类型

对于自定义数据类型,set必须指定排序规则才可以插入数据

【demo】:

#include <iostream>
#include <string>
#include <set>

using namespace std;

class Person
{
public:
Person(string name, int age)
{
this->m_name = name;
this->m_age = age;
}

public:
string m_name;
int m_age;
};

class PersonCompare
{
public:
bool operator()(const Person &p1, const Person &p2)
{
// 按照年龄降序排列
return p1.m_age > p2.m_age;
}
};
void test01()
{
Person p1("张三", 20);
Person p2("李四", 23);
Person p3("王五", 22);
Person p4("赵六", 21);

set<Person, PersonCompare> s;
s.insert(p1);
s.insert(p2);
s.insert(p3);
s.insert(p4);

for (set<Person, PersonCompare>::iterator it = s.begin(); it != s.end(); it++)
{
cout << it->m_name << "," << it->m_age << endl;
}
}
int main()
{
test01();
return 0;
}