3.8 set/multiset容器
3.8.1 set基本概念
特点:所有元素在插入时自动被排序
本质:set/multiset属于关联式容器,底层结构是用二叉树实现
set/multiset区别:
set 不允许容器中有重复元素
multiset 允许容器中有重复元素
3.8.2 set构造和赋值
构造函数:
set<T> st;
set(const set &st);
赋值:
set &operator=(const set &st);
3.8.3 set大小和交换
函数原型:
size();
empty();
swap(st);//交换两个集合容器
注意:不支持resize
3.8.4 set插入和删除
函数原型:
1 insert(elem);
2 clear();
3 erase(pos);//迭代器
4 erase(beg,end);//区间
5 erase(elem);
3.8.5 set查找和统计
函数原型:
find(key);//查找key是否存在,若存在,返回该键的元素的迭代器;若不存在,返回set.end();
count(key);//统计key的元素个数
示例:
//查找
set<int>::iterator pos = s.find(300);
if (pos != s.end())
{
cout << "find it :" << *pos << endl;
}
else
{
cout << "can not find it\n";
}
//统计
//对于set而言 统计结果只有0和1
int num = s.count(30);
cout << "num= " << num <<endl;
3.8.6 set和multiset区别
区别:
1 set不可以插入重复数据 而multiset可以
2 set插入数据的同时会返回插入结果,表示插入是否成功
(返回一个pair<set<int>::iterator,bool>的数据类型)
3 multiset不会检测数据 因此可以插入重复数据
示例:
void test03()
{
set<int> s;
pair<set<int>::iterator, bool> ret = s.insert(10);
if (ret.second)
cout << "insert succeed\n";
else
cout << "insert failed\n";
ret = s.insert(10);
if (ret.second)//返回true代表插入成功
cout << "insert succeed\n";
else
cout << "insert failed\n";
multiset<int> ms;
ms.insert(10);
ms.insert(10);
for (multiset<int>::iterator it = ms.begin(); it != ms.end(); ++it)
{
cout << *it << " ";
}
cout << endl;
}
3.8.7 pair对组创建
功能描述:成对出现的数据,利用对组可以返回两个数据
两种创建方式:
pair<T,T> p(value1,value2);
pair<T,T> p = make_pair(value1,value2);
3.8.8 set容器排序
set容器默认规则从小到大,如何改变排序规则?
--利用仿函数,可以改变排序规则
两种情况:1 内置类型 2 自定义类型
示例1:
//set容器排序 --存放内置数据类型
//写一个类型
class myCompare
{
public:
//返回值bool类型 重载的符号是()
//传入参数类型依情况而定
bool operator()(int v1, int v2)
{
return v1 > v2;
}
};
void test05()
{
//set容器在插入数据之后 就改不了数据顺序了
//必须在插入数据之前指定排序规则
//在其模板参数列表中要写一个仿函数 指定其规则
//在插数据之前 改变排序规则 降序
//放置类型
set<int,myCompare> s2;
s2.insert(10);
s2.insert(40);
s2.insert(50);
s2.insert(20);
s2.insert(30);
for (set<int, myCompare>::iterator it = s2.begin(); it != s2.end(); ++it)
{
cout <<*it << " ";
}
cout << endl;
}
示例2:
//set容器排序 --存放自定义数据类型
class Person
{
public:
friend ostream &operator<<(ostream &os, Person p);
Person(string name, int age)
{
this->m_Name = name;
this->m_Age = age;
}
string m_Name;
int m_Age;
};
ostream &operator<<(ostream &os, Person p)
{
os << p.m_Name << " " << p.m_Age;
return os;
}
//仿函数
class comparePerson
{
public:
bool operator()(const Person &p1, const Person &p2)
{
//按照年龄降序
return p1.m_Age > p2.m_Age;
}
};
void test06()
{
//自定义数据类型 必须指定排序规则 才能插入数据
set<Person,comparePerson> s;
Person p1("Mike", 20);
Person p2("John", 10);
Person p3("Mary", 30);
Person p4("Boob", 40);
//直接插入时 会报错
//由于不知道排序规则
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 << endl;
}
}
注意:存在问题 --当年龄相同时 插入失败