简介:
set中包含的元素是唯一的,集合中的元素是按照排序规则存放的,不能指定插入的位置
set采用红黑树变体的数据结构实现,属于
平衡二叉树。在插入和删除操作上比vector快
set不能用at(pos)和[]直接存取元素
multiset与set区别:set支持唯一键值,每个元素只能出现一次,但multiset中同一元素可以出现多次
不能直接修改set/multiset中元素的值,因为该容器是自动排序的。如果要修改一个元素值,应先删除,再插入
头文件:
#include<set>
基本操作:
set<int> s; //默认从小到大排列
s.insert(20); //插入元素
s.insert(30);
s.insert(20);
s.insert(40);
//遍历set
for(set<int>::iterator it = s.begin(); it != s.end(); it++) {
cout << *it << endl;
}
//删除元素
while(!s.empty()) {
set<int>::iterator it2 = s.begin();
s.erase(it2);
}
改变自动排序的规则:
set<int> s1; //从小到大
set<int, less<int>> s2; //从小到大
set<int, greater<int>> s3; //从大到小
s3.insert(10); //插入元素
s3.insert(30);
s3.insert(20);
s3.insert(40);
//注意此时的迭代器也要变
for(set<int, greater<int>>::iterator it = s3.begin(); it != s3.end(); it++) {
cout << *it << endl;
}
如何对自定义数据类型(如 student类)按照规则进行自动排序?----> 仿函数应用
//自定义数据类型
class Student{
public:
int age;
char name[64];
void printStuInfo() {
cout << "age : " << age << endl;
}
};
//仿函数
struct CompStudent{
bool operator()(const Student& left, const Student& right) {
if(left.age < right.age)
return true; //左小返回真,则从小到大排序
else
return false;
}
}
set<Student, CompStudent> s1;
Student stu1, stu2, stu3;
stu1.age = 28;
stu2.age = 19;
stu3.age = 20;
s1.insert(stu1);
s1.insert(stu2);
s1.insert(stu3);
//注意此时的迭代器也要变
for(set<Student, CompStudent>::iterator it = s1.begin(); it != s1.end(); it++) {
cout << it->age << endl;
}
如果两个student的age一样,则在上面情形下,后插入的那个会被忽略掉,如何判断
插入是否成功?----> 看insert的返回值---->pair的应用
Student stu4;
stu4.age = 28;
pair<set<Student, CompStudent>::iterator, bool> pair1 = s1.insert(stu4);
if(pair1.second == false) {
cout<< "failed." << endl;
}
set查找:
set.find(elem); // 查找elem元素,返回指向该元素的迭代器
set.count(elem); //返回elem的个数,对set,要么0,要么1,对multiset可能大于1
set.lower_bound(elem); //返回第一个>=elem的元素的迭代器
set.upper_bound(elem); //返回第一个>elem的元素的迭代器
set.equal_range(elem); //返回容器中与elem相等的上下限两个迭代器,在pair的形式返回,
//上限闭区间,下限开区间[begin, end)
equal_range使用示例:
set<int> s1;
s1.insert(10);
s1.insert(30);
s1.insert(20);
s1.insert(40);
pair<set<int>::iterator, set<int>::iterator> p = s1.equal_range(30);
set<int>::iterator it1 = p.first;
cout<<*it1<<endl; //因为是>= 应该是30
set<int>::iterator it2 = p.second;
cout<<*it2<<endl; //因为是> 应该是40
p = s1.equal_range(25);
it1 = p.first;
cout<<*it1<<endl; //因为是>= 应该是30
it2 = p.second;
cout<<*it2<<endl; //因为是> 应该是30
multiset基本操作:
因为允许重复元素,自动排序可能出现1,2,2,2,3这样的顺序,其他和set一样