蓝桥杯后,我整理了这些常用的C++ STL工具
作为一个算法竞赛的中等生,以前总觉得STL“花里胡哨”,不如自己写数组和循环踏实。但这次蓝桥杯发现,合理用STL能省很多时间,甚至避免低级错误。下面是我总结的常用知识点和踩过的坑,纯个人视角,适合和我一样的普通选手参考。
一、常用容器:动态数据处理好帮手
1. vector:动态数组怎么用?
刚开始觉得数组够用,后来发现遇到数据量不确定时,vector真的香:
- 初始化:直接指定大小和初始值,比如
vector<int> a(10, 0)
就是10个0,不用手动循环。 - 添加元素:用
push_back
往末尾加数据,读输入时特别方便:vector<int> nums; int x; while(cin >> x)nums.push_back(x); // 不知道有多少个数,直接边读边加
- 踩过的坑:删除元素时迭代器会失效!比如
vec.erase(it)
之后,得用it = vec.erase(it)
更新位置,不然继续用it
会出错。
2. map和unordered_map怎么选?
统计次数或者需要排序时用map,比如统计字符串里每个字符出现多少次,还能自动按字母顺序排好:
map<char, int> cnt;
for(char c: s) cnt[c]++; // 自动统计,c是字符,cnt[c]是次数
for(auto p: cnt) cout << p.first << ":" << p.second << endl; // 直接输出有序结果
如果不需要排序,只想快速查某个数在不在,就用unordered_map,比如判断数组里有没有重复元素,速度更快。
3. pair:存两个值的简单办法
比如函数要返回两个结果,或者图论里存“距离”和“节点号”,直接用pair:
pair<int, int> p = {3, 5}; // 第一个值是3,第二个是5
cout << p.first << "和" << p.second << endl; // 输出3和5
二、常用算法函数:高效
1. sort:排序怎么用最方便?
- 基础排序:不管是数组还是vector,直接
sort(arr, arr+n)
或者sort(vec.begin(), vec.end())
,默认从小到大排。 - 自定义排序:比如结构体按分数从高到低排,写个比较函数或者用lambda:
struct Student { int score, id; }; // 按分数降序,分数相同按id升序 sort(stu.begin(), stu.end(), [](Student a, Student b){return a.score > b.score || (a.score == b.score && a.id < b.id); });
2. 二分查找:别自己写,用STL!
自己写二分总出错,现在直接用lower_bound
找位置,比如在有序数组里找第一个大于等于目标的数:
vector<int> nums = {1,3,5,7,9};
auto it = lower_bound(nums.begin(), nums.end(), 5); // 找到5的位置
if(it != nums.end()) cout << "位置是" << it - nums.begin() << endl; // 输出2(下标从0开始)
3. fill:批量赋值超快捷
初始化大数组时,比如全部设为-1,用fill
比循环快多了:
int a[100];
fill(a, a+100, -1); // 一行搞定,数组里全是-1
三、好用的工具类
1. string:字符串处理全靠它
- 拼接:直接用
+
,比如读入多个单词拼成一句话,安全又方便:string s = "hello"; s += " world"; // 变成"hello world"
- 找子串:用
find
找某个字符或字符串的位置,比如判断有没有“abc”:if(s.find("abc") != string::npos) cout << "有这个子串" << endl;
- 长度:直接
s.size()
,不用像C语言那样算到\0
,不怕越界。
2. bitset:位运算变简单了
学状态压缩时发现的,比如用10位二进制表示状态,数1的个数很方便:
bitset<10> bs(123); // 123的二进制是001111011,自动补前导0到10位
cout << bs.count() << endl; // 输出5,因为有5个1
3. priority_queue:堆的快速实现
默认是最小堆(堆顶是最小的数),想实现最大堆得改比较方式,刚开始容易搞反:
priority_queue<int> min_heap; // 最小堆,push(3,1,2)后堆顶是1
// 最大堆需要第三个参数是greater<int>,虽然名字是“更大”,但实际是反着的
priority_queue<int, vector<int>, greater<int>> max_heap;
四、我的总结:STL对中等生的意义
以前觉得用STL是“偷懒”,现在发现:
- 省时间:比如排序、二分这种常用操作,STL自带的又快又正确,比赛时省下时间想算法。
- 少出错:STL的容器和算法经过很多人测试,比如vector的扩容、map的自动排序,比自己写安全。
- 不用求全:作为中等生,先把常用的几个(vector、map、sort、string)练熟,遇到不会的再查,慢慢积累。
当然也踩过不少坑,比如一开始分不清map和unordered_map的区别,写sort的比较函数忘记加const
引用导致编译错误。但正是这些错误,让我记住了不同场景该用什么工具。
最后:给和我一样的同学
STL就像身边的同学,刚开始可能觉得陌生,但用熟了就发现很靠谱。不用追求掌握所有细节,先从常用的开始:
- 数据会变多用vector,要排序的键值对用map,快速查找用unordered_map;
- 排序用sort,二分用lower_bound,字符串处理直接用string的各种函数;
- 遇到问题先想STL有没有对应的工具,再查用法(比如“C++ vector删除元素后迭代器怎么处理”)。
比赛后最大的感受是:能用STL解决的问题,就别自己折腾,把精力留给更难的算法题。这篇总结都是自己实实在在的体会,希望能帮到同样在学习路上的你~