跳转至

STL 标准模版库函数

在C++中,内置了一些标准的模板库,被称为STL(Standard Template Library)。平时经常使用的数据结构,比如栈、队列、向量(长度可变的数组)等。还有一些常用算法,比如排序、二分查找等。需要使用时可以直接拿过来用,不用自己实现。方便了代码的编写。

这里列举一些常用的模板,其他模板可以到 cplusplus.com 或百度上搜索。

STL在使用前需加上对应头文件和 using namespace std;

以下所有T都表示需要存放的数据类型,如 int。

1. 栈

1
2
3
4
5
6
头文件stack
定义stack<T> s;
压入s.push(x);//O(1)
弹出s.pop();//O(1)
查看栈顶元素s.top();//O(1)
查看栈里的元素个数s.size();//O(1)

2. 队列

1
2
3
4
5
6
头文件queue
定义queue<T> q;
入队q.push(x);//O(1)
出队q.pop();//O(1)
查看队首元素q.front();//O(1)
查看队列里的元素个数q.size();//O(1)

3. 向量

1
2
3
4
5
6
头文件vector
定义vector<T> a;
尾部加入一个元素a.push_back(x);//O(1)
查看元素个数a.size();//O(1)
查看第i个元素a[i];//O(1)
遍历for(int i=0;i<a.size();i++)printf("%d ",a[i]);

4. 排序

1
2
3
4
5
6
7
8
头文件algorithm
如果要对a[l]~a[r]从小到大排序
sort(a+l,a+r+1);//O(nlogn) n为长度
如果要对a[l]~a[r]从大到小排序
bool cmp(T x,T y){
    return x>y;
}
sort(a+l,a+r+1,cmp);

5. 字符串

头文件string
定义string s;
长度s.size();//O(1)
第i个字符下标从0开始到size-1:s[i];//O(1)
翻转s.reverse();//O(n)
赋值s=a;//O(n),a可以是一个string,一个char数组或char类型
在后面加一个字符或字符串s+=a;//O(a的长度),a的类型同上
插入删除替换查找取子串比较inserterasereplacefindsubstrcompare
//参考: https://legacy.cplusplus.com/reference/string/string/?kw=string
按字典序比较使用比较符号即可
连接两个字符串s1+s2
输入cin>>s;
输出cout<<s;
输入一行getline(cin,s);

以上为入门组要求掌握的STL用法


迭代器概念:iterator C++迭代器(STL迭代器)

下面用 it 表示相应的迭代器

6. 集合

该集合与数学中的集合定义类似不存在相等的元素
即不存在元素x与y使得x<y与y<x同时不成立
set使用红黑树实现是一个平衡树
头文件set
定义set<T> s;
插入s.insert(x);//O(logn)
删除s.erase(x);//O(logn),x可以为值或者迭代器
元素个数s.size();//O(1)
清空集合s.clear();//O(n)
前一个元素prev(it);//O(1)
后一个元素next(it);//O(1)
使迭代器向后移动一个元素++it;//O(1)
使迭代器向前移动一个元素--it;//O(1)
从小到大遍历for(set<T>::iterator it=s.begin();it!=s.end();++it)//O(n)
从大到小遍历for(set<T>::reverse_iterator it=s.rbegin();it!=s.rend();++it)//O(n)
查找s.find(x);//O(logn),若找到了则会返回相应元素的迭代器,若没找到则会返回s.end(),下同
查找大于等于x的第一个元素s.lower_bound(x);//O(logn)
查找大于x的第一个元素s.upper_bound(x);//O(logn)

7. 多重集合

1
2
3
4
5
6
与set类似但是可以存在相等的元素
要注意在erase时最好使用迭代器删除
若用值删除则会把相等的元素全都删掉
头文件set
定义multiset<T> s;
统计x的个数s.count(x);//O(logn)

8. 双端队列

1
2
3
4
5
6
7
8
9
头文件queue
定义deque<T>q;
队尾pushq.push_back(x);
队首pushq.push_front(x);
队尾popq.pop_back();
队首popq.pop_front();
查看队尾q.back();
查看队首q.front();
复杂度均为O(1)

9. 优先队列(大根堆)

1
2
3
4
5
6
头文件queue
定义priority_queue<T> q;
插入q.push(x);//O(logn)
删除最大值q.pop();//O(logn)
查看最大值q.top();//O(1)
查看元素个数q.size();//O(1)

10. 映射(字典)

map是一个值到另一个值的映射类似python里的字典
每一对值分为键key和值value以key当做查找的关键字
map也是用红黑树实现的各个操作复杂度同set
头文件map
定义map<T1,T2> a;
赋值a[x]=y;//O(logn)若已有键x,那么将其对应的值改成y
//否则插入一对新的键值x和y
取x对应的值a[x];//O(logn)
查找是否存在键xa.find(x);O(logn)//若找到则会返回对应迭代器,否则返回a.end()
//若想看键x是否存在,一定要用find,而不要用中括号
查看该迭代器的键it->first
查看该迭代器的值it->second
删除元素a.erase(it)//O(1)用法同set

11. 无序映射

1
2
3
4
头文件unordered_map
定义unordered_map<T1,T2>a;
用法与map一样但是是用哈希表实现的
所以本来 O(logn)的复杂度的操作在平均情况下都为O(1)但是在非常极端的情况下一次操作为O(n)

杂项

1. 前缀和

C++ 基本不用的 stl ,把a到b的前缀和存到c...容器

1
2
3
4
5
6
partial_sum(begin(nums), end(nums), begin(nums));

//此处原地更新,等价于
for(int i=1; i<nums.size(); ++i){
    nums[i] += nums[i-1];
}