set翻译为集合,是一个内部自动有序且不含重复元素的容器。在考试中有可能出现需要去掉重复元素的情况,而且有可能因这些元素比较大或者类型不是int型而不能直接开散列表,在这种情况下就可以用set来保留元素本身而不考虑它的个数。当然,上面说的情况也可以通过再开一个数组进行下标和元素的对应来解决,但是set提供了更为直观的接口,并且加入set知乎可以实现自动排序,因此熟练使用set可以在做某些题时减少思维量。
#include<iostream>
#include<set>
using namespace std;
int main()
{
//from liuchuo
set<int> s; //定义一个空集合s
s.insert(1); //插入1
cout << *(s.begin()) << endl; //1 //输出第一个(星号表示要对指针取值)
for (int i = 1; i <= 5; i++) {
s.insert(i);
}
for (set<int>::iterator it = s.begin(); it != s.end(); it++) {
cout << *it << ' '; //1 2 3 4 5
}
cout << endl << "s.find(2) != s.end() " << (s.find(2) != s.end()) << endl; //1
//查找集合s中的值,如果结果等于s.end表示未找到(因为s.end()表示s的最后一个元素的下一个元素所在的位置)
cout << "s.find(10) != s.end() " << (s.find(10) != s.end()) << endl; //0
//s.find(10) != s.end()表示能找到10这个元素
s.erase(1); //删除集合s中1这个元素
cout << "s.find(1) != s.end() " << (s.find(1) != s.end()) << endl; //0 //这时候元素1就找不到了
//set内元素的访问
//set只能通过迭代器访问
//由于除开vector和string之外的STL容器都不支持*(it+i)的访问方式,因此只能如下枚举
set<int> st;
st.insert(3);
st.insert(5);
st.insert(2);
st.insert(3);
//注意:不支持it < st.end()的写法
for (set<int>::iterator it = st.begin(); it != st.end(); it++) {
cout << *it << ' '; //2 3 5
}
cout << endl;
//可以发现,set内元素自动递增排序,且自动去重
//find() 操作
//find(value)返回set中对应值为value的迭代器,时间复杂度ologn,n为set内元素个数
//find()返回一个指向被查找到元素的迭代器
set<int> b;
for (int i = 1; i <= 3; i++) {
b.insert(i);
}
if (b.find(2) != b.end()) {
auto k = b.find(2);
cout << *k << endl; //2
}
//erase()操作
//删除单个元素
//st.erase(it) it为所需删除的元素的迭代器,可结合find使用
set<int> a;
a.insert(100);
a.insert(200);
a.insert(100);
a.insert(300);
a.erase(a.find(100)); //find()函数找到100,然后erase删除
a.erase(a.find(200));
for (auto it = a.begin(); it != a.end(); it++) {
cout << *it << ' '; //300
}
cout << endl;
//st.erase(value) value为所需要删除元素的值。
a.insert(100);
a.insert(200);
a.erase(200);
for (auto it = a.begin(); it != a.end(); it++) {
cout << *it << ' '; //100 300
}
cout << endl;
//删除一个区间内所有元素
//st.erase(first,last)可以删除一个区间内的所有元素
//first为所需删除区间的起始迭代器,而last为所需删除区间的末尾迭代器的下一个地址
//即为删除[first,last)
set<int> c;
c.insert(20);
c.insert(30);
c.insert(10);
c.insert(40);
set<int>::iterator l = c.find(30);
c.erase(l, c.end()); //删除元素30至set末尾之间的元素 即30和40
for (l = c.begin(); l != c.end(); l++) {
cout << *l << ' '; //10 20
}
cout << endl;
return 0;
}
set的常见用途:
set最主要的作用是自动去重并按升序排序,因此碰到需要去重但是却不方便直接开数组的情况,可以尝试用set解决。
延伸:set中元素是唯一的,如果需要处理不唯一的情况,则需要使用multiset。另外C++11标准中还增加了unordered_set,以散列代替set内部的红黑树实现,使其可以用来处理之去重但不排序的需求,速度比set要快得多。