set容器
set容器的特点:
所有元素都会根据元素的键值自动被排序。
set的元素即是键值又是实值。
set容器的键值 不允许相同。
set容器提供的是只读迭代器(不允许用户修改元素的内容)
set容器的API
1、set容器的插入删除
set构造函数
set<T> st;//set默认构造函数:
mulitset<T> mst; //multiset默认构造函数:
set(const set &st);//拷贝构造函数
set赋值操作
set& operator=(const set &st);//重载等号操作符
swap(st);//交换两个集合容器
set大小操作
size();//返回容器中元素的数目
empty();//判断容器是否为空
set插入和删除操作
insert(elem);//在容器中插入元素。
clear();//清除所有元素
erase(pos);//删除pos迭代器所指的元素,返回下一个元素的迭代器。
erase(beg, end);//删除区间[beg,end)的所有元素 ,返回下一个元素的迭代器。
erase(elem);//删除容器中值为elem的元素
void test01()
{
set<int> s;
//set容器自动根据键值排序
s.insert(30);
s.insert(10);
s.insert(20);
s.insert(50);
s.insert(40);
for_each(s.begin(),s.end(),[](int val){
cout<<val<<" ";
});//10 20 30 40 50
cout<<endl;
//set容器提供的是只读迭代器const_iterator
//用户不可以修改set容器的元素
set<int>::const_iterator it=s.begin();
//*it = 100;//err
cout<<"size = "<<s.size()<<endl;
//删除起始位置的元素
s.erase(s.begin());
for_each(s.begin(),s.end(),[](int val){
cout<<val<<" ";
});//20 30 40 50
cout<<endl;
//根据元素删除
s.erase(40);
for_each(s.begin(),s.end(),[](int val){
cout<<val<<" ";
});//20 30 50
cout<<endl;
}
2、set容器的查找
set查找操作
find(key);//查找键key是否存在,若存在,返回该键的元素的迭代器;
若不存在,返回set.end();
count(key);//查找键key的元素个数
*/
void test02()
{
set<int> s;
//set容器自动根据键值排序
s.insert(30);
s.insert(10);
s.insert(20);
s.insert(50);
s.insert(40);
//find(key);//查找键key是否存在,若存在,返回该键的元素的迭代器;
//若不存在,返回set.end();
set<int>::const_iterator ret;
ret = s.find(20);
if(ret == s.end())
{
cout<<"没有找到"<<endl;
}
else
{
cout<<"找到"<<*ret<<endl;
}
//count(key);//查找键key的元素个数
//set容器的键值 是不重复的 那么count(key)只能是1或0
cout<<s.count(20)<<endl;//1
cout<<s.count(200)<<endl;//0
}
运行结果:
3、set容器的lower_bound和upper_bound
lower_bound(keyElem);//返回第一个key>=keyElem元素的迭代器。
upper_bound(keyElem);//返回第一个key>keyElem元素的迭代器。
lower_bound(keyElem);//返回第一个key>=keyElem元素的迭代器。
upper_bound(keyElem);//返回第一个key>keyElem元素的迭代器。
equal_range(keyElem);//返回容器中key与keyElem相等的上下限的两个迭代器
void test03()
{
set<int> s;
//set容器自动根据键值排序
s.insert(30);
s.insert(10);
s.insert(20);
s.insert(50);
s.insert(40);
//下限:lower_bound(keyElem);//返回第一个key>=keyElem元素的迭代器。
set<int>::const_iterator lower_ret;
lower_ret = s.lower_bound(30);
if(lower_ret == s.end())
{
cout<<"没有找到30的下限"<<endl;
}
else
{
cout<<"找到30的下限:"<<*lower_ret<<endl;
}
//upper_bound(keyElem);//返回第一个key>keyElem元素的迭代器
set<int>::const_iterator up_ret;
up_ret = s.upper_bound(30);
if(up_ret == s.end())
{
cout<<"没有找到30的上限"<<endl;
}
else
{
cout<<"找到30的上限:"<<*up_ret<<endl;
}
//equal_range(keyElem);//返回容器中key与keyElem相等的上下限的两个迭代器
//equal_range 返回的是对组
//first 对组中第一个值 second对组中第二个值
pair<set<int>::const_iterator , set<int>::const_iterator> pair_ret;
pair_ret = s.equal_range(30);
//下限lower_bound
if(pair_ret.first == s.end())
{
cout<<"下限未找到"<<endl;
}
else
{
cout<<"下限找到:"<< *(pair_ret.first) <<endl;
}
//上限upper_bound
if(pair_ret.second == s.end())
{
cout<<"上限未找到"<<endl;
}
else
{
cout<<"上限找到:"<< *(pair_ret.second) <<endl;
}
}
运行结果:
4、对组
void test04()
{
//9527--星爷 10086--移动 10010--联通
//定义对组方式1:
pair<int,string> pair1(9527,"星爷");
cout<<"编号:"<<pair1.first<<",人物:"<<pair1.second<<endl;
//定义对组方式1:(推荐)
pair<int,string> pair2 = make_pair(10086,"移动");
cout<<"编号:"<<pair2.first<<",人物:"<<pair2.second<<endl;
}
运行结果:
5、更改set容器的默认排序规则(推荐使用仿函数)
class MyGreater
{
public:
bool operator()(int val1, int val2)
{
return val1>val2;
}
};
void test05()
{
//默认从小-->大排
//改成从大-->小排
//set<int,排序规则> s;
set<int,MyGreater> s;
s.insert(30);
s.insert(10);
s.insert(20);
s.insert(50);
s.insert(40);
for_each(s.begin(),s.end(),[](int val){cout<<val<<" ";});
cout<<endl;
}
int main(int argc, char *argv[])
{
test05();
return 0;
}
运行结果:
6、set容器存放自定义数据的时候 重载<运算符
class Person
{
public:
string name;
int age;
Person(string name, int age)
{
this->name =name;
this->age = age;
}
//方法一:重载<运算符 小-->大
bool operator<(const Person &ob)const
{
return this->age < ob.age;
}
};
void test06()
{
set<Person> s;
s.insert(Person("德玛西亚", 19));
s.insert(Person("小法", 18));
s.insert(Person("小炮", 21));
s.insert(Person("风男", 29));
for_each(s.begin(),s.end(),[](Person val){
cout<<"name="<<val.name<<", age="<<val.age<<endl;
});
}
运行结果:
7、set容器存放自定义数据的时候 指定排序规则。
class Person
{
public:
string name;
int age;
Person(string name, int age)
{
this->name =name;
this->age = age;
}
#if 0
//方法一:重载<运算符 小-->大
bool operator<(const Person &ob) const
{
//单纯的告诉编译器 该函数为常函数不会修改成员数据
//常对象 调用 常函数
return this->age < ob.age;
}
#endif
};
class myGreaterPerson
{
public:
bool operator()(const Person &ob1, const Person &ob2)
{
return ob1.age > ob2.age;
}
};
void test06()
{
//方法二:指定排序规则
set<Person, myGreaterPerson> s;
s.insert(Person("德玛西亚", 19));
s.insert(Person("小法", 18));
s.insert(Person("小炮", 21));
s.insert(Person("风男", 29));
for_each(s.begin(),s.end(),[](Person val){
cout<<"name="<<val.name<<", age="<<val.age<<endl;
});
}
运行结果:
multiset容器
multiset特性及用法和set完全相同,唯一的差别在于它允许键值重复
允许插入重复的键值
1、set容器不允许插入相同的key值
void test07()
{
set<int> s;
pair<set<int>::const_iterator, bool> ret1;
pair<set<int>::const_iterator, bool> ret2;
ret1 = s.insert(10);
if(ret1.second == true)
{
cout<<"第一次插入成功"<<endl;
}
else
{
cout<<"第一次插入失败"<<endl;
}
ret2 = s.insert(10);
if(ret2.second == true)
{
cout<<"第二次插入成功"<<endl;
}
else
{
cout<<"第二次插入失败"<<endl;
}
for_each(s.begin(),s.end(),[](int val){
cout<<val<<" "<<endl;
});
cout<<endl;
}
运行结果:
2、multiset可以插入重复的键值
void test07()
{
multiset<int> s;
s.insert(10);
s.insert(10);
for_each(s.begin(),s.end(),[](int val){
cout<<val<<" "<<endl;
});
cout<<endl;
}
运行结果: