网上类似的博客有很多,我写这个博客主要是为了帮助自己和大家记住STL这几个容器相关的语法
结构体的排序
这三个容器都要求其中的元素可以排序,当插入元素为结构体时,需要通过重载运算符为结构体自定义排序方法。
1
2
3
4
5
6struct S{
ll id,v;
bool operator< (const S &a)const{
return v<a.v;
}
}s[100];若对s结构体数组赋值后排序,则从左到右v依次增大
可以理解为v
代表左边那个,以参数形式传入的a.v
代表右边那个,执行完排序之后,结构体中相邻两个元素满足return
中的条件,上面的代码可以理解为排序之后左边的v<右边的v
set
C++的set是利用平衡二叉树实现的一个容器,具有以下特点
- 对于插入、删除和查找操作,set保证其时间复杂度都是$O(\log_2n)$(n是set中元素的个数)。
- set是一个有序的、可以前向和后向遍历的容器(双向迭代器)。
- set的元素可以插入、删除,但是不可更改。
- set中的元素不可重复。
至于具体的原理去学习一下二叉排序树和平衡二叉树就会了解了
插入
1
.insert();
删除
1
.erase();
判断是否存在
1
.count();
count()
本来是STL中用来判断某个元素出现多少次的函数,由于set中元素不能重复,返回值为0或1。
遍历
1
2
3
4
5
6
7set<int> s;
int main(int argc, char const *argv[]) {
for(int i=0;i<10;++i)
s.insert(i);
for(std::set<int>::iterator it=s.begin();it!=s.end();++it)
cout<<*it<<" ";
}C++11的新语法遍历(Range-based for loop)
1
2
3
4
5
6
7set<int> s;
int main(int argc, char const *argv[]) {
for(int i=0;i<10;++i)
s.insert(i);
for(auto &v:s)
cout<<v<<" ";
}输出均为
1
0 1 2 3 4 5 6 7 8 9
反向遍历
1
2
3
4
5
6
7set<int> s;
int main(int argc, char const *argv[]) {
for(int i=0;i<10;++i)
s.insert(i);
for(std::set<int>::reverse_iterator rit=s.rbegin();rit!=s.rend();++rit)
cout<<*rit<<" ";
}
遍历删除
1
2for(set<int>::iterator it=s.begin();it!=s.end();)
s.erase(it++);
选择性遍历删除
1
2
3
4for(set<int>::iterator it=s.begin();it!=s.end();)
if((*it)%2)
s.erase(it++);
else it++;删除set中的奇数
设置排序优先级
int或long long
默认从小到大
使用1
set <int, greater<int> > setTest;
可以从大到小排序(可以理解为左边的大,所以叫greater)
- 结构体使用上文说的重载运算符来设置排序优先级
map
priority_queue