STL常用容器 目录:
1. string容器
2. vector容器
3. deque容器
4. stack容器
5. queue容器
6. list容器
7. set/multiset容器
7.1 set/multiset基本概念
所有元素都会在插入时自动被排序。set/multiset属于关联式容器,底层结构是用二叉树实现。
set和multiset区别:
- set不允许容器中有重复的元素
- multiset允许容器中有重复的元素
都包含头文件set即可
7.2 set/multiset构造和赋值
功能描述:
- 创建set容器以及赋值
函数原型:
set<T> st;
//默认构造函数set(const set &st);
//拷贝构造函数set& operator=(const set& lst);
//赋值:重载等号操作符
set在插入数据时,没有posh的操作了,只能采用insert
方法
set<int>s1;
//插入数据
s1.insert(10);
s1.insert(40);
s1.insert(30);
s1.insert(20);
s1.insert(30);
//遍历容器
printSet(s1);//10 20 30 40
//拷贝构造
set<int>s2(s1);
//赋值
set<int>s3;
s3 = s2;
set特点:所有元素插入时候(insert)自动被排序;且不允许插入重复值(set会自动删掉)
7.3 set/multiset大小和交换
功能描述:
- 统计set容器的大小以及交换set容器
函数原型:
empty();
//判断容器是否为空size();
//返回容器中元素的个数swap(st);
//交换两个集合容器
不允许指定大小,因为如果指定过长,都要用0来填充,那么set就有重复数据了,但这是不允许的。
7.4 set/multiset插入和删除
功能描述:
- 对set容器进行插入、删除操作
函数原型:
insert(elem);
//在容器中插入元素clear();
//清除容器中所有元素erase(pos);
//删除pos位置的数据,返回下一个元素的迭代器erase(beg, end);
//删除[beg, end)区间的元素,返回下一个元素的迭代器erase(elem);
//删除容器中值为elem的元素
set<int>s1;
//插入数据
s1.insert(30);
s1.insert(20);
s1.insert(40);
s1.insert(10);
//遍历
printSet(s1);//10 20 30 40
//删除
s1.erase(s1.begin());
printSet(s1);//20 30 40
//删除的是10,不是30!!!!
//删除重载版本
s1.erase(30);
printSet(s1);//20 40
7.5 set/multiset查找和统计
功能描述:
- 对set容器进行查找数据以及统计数据
函数原型:
find(key);
//在查找key是否存在,若存在,返回该键的元素的迭代器;若不存在,返回set.end()count(key);
//统计key的元素个数
//查找
set<int>::iterator pos = s1.find(30);//用迭代器去接收
if (pos != s1.end())
{
cout << "找到元素:" << *pos << endl;
}
else
{
cout << "未找到元素" << endl;
}
//统计
int num = s1.count(30);
cout << "num = " << num << endl;
对于set而言,查找返回的结果是迭代器;统计的结果要么是0,要么是1(因为set不允许重复)
7.6 set和multiset区别
- set不可以插入重复数据,而multiset可以
- set插入数据的同时会返回插入结果,表示插入是否成功
- multiset不会检测数据,因此可以插入重复数据
set不允许插入重复数据的原因在于,其实set返回的是一个pair(迭代器, bool)。如果重复,那么bool值为false,将不会插入成功,如下:
set<int>s;
pair<set<int>::iterator, bool> ret = s.insert(10);
if (ret.second)//第一次插入成功
{
cout << "第一次插入成功" << endl;
}
else
{
cout << "第一次插入失败" << endl;
}
ret = s.insert(10);
if (ret.second)//第二次插入失败
{
cout << "第二次插入成功" << endl;
}
else
{
cout << "第二次插入失败" << endl;
}
7.7 pair对组创建
功能描述:
- 成对出现的数据,利用对组可以返回两个数据
- 使用对组时,并不需要包含其它额外的头文件
函数原型:
pair<type, type> p (value, value2);
pair<type, type> p = make_pair(value, value2);
调用:p.first;
//调用对组p的第一个参数值p.second;
//调用对组p的第二个参数值
pair<string, int>p("Tom", 20);
cout << "姓名:" << p.first << " 年龄:" << p.second << endl;
pair<string, int>p2 = make_pair("Jerry", 30);
cout << "姓名:" << p2.first << " 年龄:" << p2.second << endl;
7.8 set容器排序
功能描述:
- set容器默认排序规则为从小到大,但排序规则可以改变
主要技术点:
- 利用仿函数,可以改变排序规则
示例一:set存放内置数据类型
class Mycompare
{
public:
bool operator()(int v1, int v2)const//小括号重载
{
return v1 > v2;
}
};
void test01()
{
set<int, Mycompare>s1;
s1.insert(10);
s1.insert(40);
s1.insert(20);
s1.insert(50);
s1.insert(30);
for (set<int, Mycompare>::iterator it = s1.begin(); it != s1.end(); it++)
{
cout << *it << " ";
}
cout << endl;//50 40 30 20 10
}
需要自定义一个类,其中包含重载小括号的仿函数,并返回bool类型,输入的参数与set<int, Mycompare>s1;
的第一个参数保持一致,set<>中的第二个参数为自定义的类名。
示例二:set存放自定义数据类型
class Person
{
public:
Person(string name, int age)
{
this->m_Name = name;
this->m_Age = age;
}
string m_Name;
int m_Age;
};
class comparePerson
{
public:
bool operator()(const Person&p1, const Person&p2)const//小括号重载
{
//按照年龄降序
return p1.m_Age > p2.m_Age;
}
};
void test01()
{
//自定义数据类型都会指定排序规则
set<Person, comparePerson>s;
Person p1("Jenny", 24);
Person p2("Bob", 28);
Person p3("Anny", 25);
Person p4("Sarah", 21);
s.insert(p1);
s.insert(p2);
s.insert(p3);
s.insert(p4);
for (set<Person, comparePerson>::iterator it = s.begin(); it != s.end(); it++)
{
cout << "姓名:" << it->m_Name << " 年龄:" << it->m_Age << endl;
}
}
【未完待续】