本篇文章之所以诞生,是由于在刷PAT时需要掌握STL模板库,所以特意测试学习了常用的方法。仅适用于G++环境下的单线程单文档情况。对于多文档多线程情况不保证正确性。如果你是只想在数据结构与算法比赛中多拿一些AC而学习STL,小码农自认它还是挺好的。如果是项目需要而学习STL,还是建议读官方文档。
如果你觉得博文状态下阅读费劲,可以去我的github下载源码。如果出现对不齐的情况,把编辑器Tab键缩进设置成4个就可以了。欢迎指点评论。
#include<bits/stdc++.h>
using namespace std;
/*
下面的注释:
1)DT : data type
2)遍历说明:以集合名开头的都是遍历本次测试使用到的集合的结果,
由于太多cout会使调理不清晰,便直接放上输出结果。
*/
bool cmp(const int &e1, const int &e2){ return e1 > e2; }
int main()
{
/*
1、创建、
1):默认创建: set<DT> s1;
2):拷贝创建: set<DT> s2(s1);
3):用其他set的某一段创建: set<DT> s3(iterator it1, iterator it2);
4):截取数组中某段([begin, end))创建: set<DT> s3(&arr[begin], &arr[end]);
*/
int arr[10] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
set<int> s1;
set<int> s4(&arr[4], &arr[8]);
set<int> s2(s4);
set<int> s3(s2.begin(), s2.end());
/* Console: s1:
s2: 5 6 7 8
s3: 5 6 7 8
s4: 5 6 7 8 */
/*
2、插入:
1)插入单个元素: pair<set<DT>::iterator, bool> insert(DT data);
原set中没有data返回true,否则返回false
2)插入其他set的一部分: void insert(iterator it1, iterator it2);
3)插入数组的一部分([begin, end)): void insert(&arr[begin], &arr[end]);
*/
pair<set<int>::iterator, bool> ret = s1.insert(100);
s1.insert(s4.begin(), s4.end());
s1.insert(&arr[8], &arr[9]);
cout << *ret.first << endl;
/*Console: 100
s1: 5 6 7 8 9 100 */
/*
3、获取元素:set中元素会自动排序,所以不能通过索引获得元素
1)获得首元素之前位置的迭代器: set<DT>::iterator begin();
2)获得尾元素之后位置的迭代器: set<DT>::iterator end();
取出迭代器之后紧邻的元素使用 *,如 *it
*/
for(set<int>::iterator it = s1.begin(); it != s1.end(); it++)
cout << *it << " ";
cout << endl;
set<int>::iterator itb = s1.begin();
set<int>::iterator ite = s1.end();
ite--;
cout << *itb << " " << *ite << endl;
/*Console: 5 100 */
/*
4、删除元素:
1)删除迭代器指向的元素: void erase(iterator it);
2)删除指定的元素: int erase(DT data);
返回0表示删除失败,即set中没有此元素;返回1表示删除成功,即set中有此元素。
3)删除两迭代器区间的元素: void erase(iterator it1, iterator it2);
4)清空set: void clear();
*/
set<int>::iterator itb4 = s1.begin();
s1.erase(itb4);
int e1 = s1.erase(50);
int e2 = s1.erase(100);
cout << e1 << " " << e2 << endl;
/* Console: 0 1
s1: 6 7 8 9 */
/*
5、修改:
1)修改某元素的值:不能直接操作,只能用增加、删除的方式: insert();、 erase();
2)交换两个set: void swap(set& x);
*/
s1.swap(s2);
/*Console: v1: 5 6 7 8
v2: 6 7 8 9 */
/*
6、遍历:
只能通过迭代器的方式: for(set<DT>::iterator it = s.begin(); it != s.end(); it++)
*/
for(set<int>::iterator it = s1.begin(); it != s1.end(); it++)
cout << *it << " ";
cout << endl;
/*Console: v1: 5 6 7 8 */
/*
7、查找:
返回迭指向该数据之前位置的迭代器: iterator find(DT val);
找不到时返回指向尾元素之后的迭代器
返回是否存在: int count(DT val);
*/
set<int>::iterator it71 = s1.find(5);
set<int>::iterator it72 = s1.find(100);
it72--;
cout << *it71 << " " << *it72 << endl;
/*Console: 5 8 */
int c1 = s1.count(100);
int c2 = s1.count(5);
cout << c1 << " " << c2 << endl;
/*Console: 0 1 */
/*
8、自定义排序规则
使用decltype,传入自定义排序规则
*/
set<int, decltype(cmp)*> s8(cmp);
for(int i = 0; i < 10; i++)
s8.insert(i);
/*Console: 9 8 7 6 5 4 3 2 1 0 */
/*
9、其他:
1)赋值号: set& operator= (const set& x);
返回指向当前set的指针
2)数据个数: int size();
3)等于号: operator==
*/
set<int> s9 = s1;
cout << s9.size() << endl;
cout << (s9 == s1) << endl;
/*Console: 4
1
s9: 5 6 7 8 */
return 0;
}