应该要掌握的STL
应该要掌握的STL
1. vector
假设我们有一个vector<typename>
变量v
,那么我们就可以有如下操作:
v.push_back(obj)
,可以在v
的最后插入一个obj
v.pop_back()
可以弹出v
最后一个元素v.size()
可以返回v
中元素的个数可以直接通过
v[i]
访问vector
中的元素1
2for (int i=0; i<v.size(); i++)
#可以直接用v[i]访问vector中的元素sort(v.begin(),v.end(),cmp)
可以对v
进行排序v.clear()
清空vector v
2.priority_queue(优先队列,即堆,默认大根堆)
假设我们有一个priority_queue<node>
变量heap
,那么我们就可以有如下操作:
heap.push(obj)
可以把一个元素加入堆heap.pop()
可以弹出堆顶元素node tmp = heap.top()
可以获得堆顶元素自定义结构体类型的重载运算符
1
2
3
4
5
6
7struct node {
int x,id;
}
bool operator < (const node &a, const node &b) {
return a.x < b.x; //以x为关键字从大到小实现大根堆
return a.x > b.x; //以x为关键字从小到大实现小根堆
}
3.lower_bound & upper_bound(可以对数组和vector )(注意需要事先排序)
int tmp1 = lower_bound(a + 1,a + n + 1,obj) - a
返回数组a
中第一个大于等于obj
的元素的下标int tmp2 = upper_bound(a + 1,a + n + 1,obj) - a
返回数组a
中第一个大于obj
的元素的下标。int tmp1 = lower_bound(v.begin(),v.end(),obj) - v.begin()
返回数组a
中第一个大于等于obj
的元素的下标int tmp1 = upper_bound(v.begin(),v.end(),obj) - v.begin()
返回数组a
中第一个大于obj
的元素的下标
4.unqiue (可以对数组和vector) (注意需要事先排序)
1 | int a[] = {0,2,5,3,2,3,5}; |
输出:
1 | m = 3 |
5.bitset
- 新建一个长度为30的
bitset
并给它赋值为a
:bitset<30> s(a);
- 可以直接用
s[i]
访问这个bitset
,既可以取值,也可以修改。注意:s[0]
是最低位,s[29]
是最高位。 - 可以把两个
bitset
互相做位运算,也可以对两个bitset
做==
!=
的比较,还可以对bitset
进行左移右移。 s.count()
返回有几个1
- 如果
s
所有位全部是0
,那么s.any()
返回False
,s.none()
返回True
- 如果
s
至少有一位是1
,那么s.any()
返回True
,s.none()
返回False
- 一个使用实例
1 | a = 20; |
1 | 20 |
- 注意:
s[0]
的类型不是int
,但可以强制转换为int
,所以可以这样int tmp = s[0]
,但不能printf("%d\n",s[0])
,如果要直接printf
,那么应该printf("%d\n",(int)s[0])
.
6. multiset/set
所有multiset的操作只要把“multiset”换成”set"就可以了,故下面用multiset演示
声明方式:
multiset<int> s
或multiset<node> s;
注意,如果用了后者,那么需要重载
<
运算符,重载方法和前面在priority_queue
里面重载的方法一样。然后,set
和multiset
默认都是从小到大排序的,所以如果要按照node
里的x
关键字排序,重载函数应该这样写:1
2
3bool operator < (const node &a, const node &b) {
return a.x < b.x;
}multiset
的迭代器的概念:- 声明一个
multiset
的迭代器:multiset<node>::iterator it;
multiset
的迭代器仅支持++
和--
两个操作,分别表示在multiset
中向后或者向前一个元素- 如果我们有一个
multiset
的迭代器it
,可以通过*it
来表示迭代器it
指向的元素(有点像一个指针)
- 声明一个
假设我们有一个multiset<int> s;
s.size(), s.erase(), s.clear()
均支持。s.insert(obj)
可以实现往里面插入元素的功能s.find(obj)
可以返回一个multiset
的迭代器,如果找不到对应元素那么就会返回s.end()
,否则返回对应元素的迭代器,可以通过*
运算得到对应元素。设
it
是一个multiset
的迭代器,那么s.erase(it)
可以删除这个迭代器对应的元素。s.erase(obj)
可以删除所有对应元素。s.count(obj)
可以返回s
中有多少个元素等于obj
s.lower_bound(obj)
可以返回第一个大于等于obj
的元素的迭代器s.upper_bound(obj)
可以返回第一个大于obj
的元素的迭代器
可以通过这个方式输出
multiset s
中的元素(默认是从小到大排序的)1
2for (multiset<int>::iterator it = s.begin(); it != s.end(); it++)
printf("%d ",*it);
7. pair
声明方法:
pair<typename1,typename2> tmp;
例如:
pair<pair<int,int>, vector<int> > tmp;
一种构造方法:
pair<int, int> p = make_pair(2,3)
假设我们有一个
pair<int, int> p;
那么可以通过p.first
和p.second
分别访问第一个元素和第二个元素。
8. map
map
也有insert(), clear(), empty()
的操作
假设我们有一个map<int,int> mp;
和一个map<int,int>::iterator it;
-
往map
里插入一个键值对:mp.insert(make_pair(2,3))
删除迭代器
it
对应的元素:mp.erase(it)
删除
map
中的pair
:mp.erase(make_pair(2,3))
通过
key
来删除map
中的pair
:mp.erase(2)
mp.find(make_pair(2,3))
在m
中找对应元素,返回迭代器。如果不存在,返回mp.end()
mp[key]
返回key
值对应的value
,可以直接赋值或访问(和python里的字典一样),如果不存在mp[key]
,则直接新建一个空二元组(key,zero)