杨校老师课堂之C++备赛信奥中STL常用库函数梳理汇总(含样例代码)
🔹 一、STL 容器(Containers)
1. vector(动态数组)
- 头文件:
#include - 特点:可变长数组,支持随机访问
- 常用方法:
push_back(),pop_back(),front(),back()size(),empty(),clear(),resize()begin(),end(),insert(),erase()at(),[]下标访问
2. stack(栈)
- 头文件:
#include - 特点:后进先出(LIFO)
- 常用方法:
push(),pop(),top()empty(),size()
3. queue(队列)
- 头文件:
#include - 特点:先进先出(FIFO)
- 常用方法:
push(),pop(),front(),back()empty(),size()
4. deque(双端队列)
- 头文件:
#include - 特点:两端都可插入删除
- 常用方法:
push_front(),push_back()pop_front(),pop_back()front(),back()clear(),size(),empty()
5. priority_queue(优先队列)
- 头文件:
#include - 特点:自动排序,默认大根堆
- 常用方法:
push(),pop(),top()empty(),size()
- 自定义排序:使用
greater<>或自定义比较函数/结构体
6. map / unordered_map(映射)
- 头文件:
#include或#include - 特点:键值对存储,map 有序,unordered_map 无序(哈希实现)
- 常用方法:
insert(),erase(),find(),count()[]访问,at()lower_bound(),upper_bound()size(),empty(),clear()
7. set / unordered_set(集合)
- 头文件:
#include或#include - 特点:元素唯一,set 有序,unordered_set 无序
- 常用方法:
insert(),erase(),find(),count()lower_bound(),upper_bound()size(),empty(),clear()
8. pair(二元组)
- 头文件:
#include - 特点:存储两个元素
- 常用方法:
first,second访问元素make_pair()构造
9. string(字符串)
- 头文件:
#include - 特点:动态字符序列
- 常用方法:
append(),push_back(),insert(),erase()substr(),find(),rfind()c_str(),size(),length(),empty()stoi(),to_string()
10. bitset(位集)
- 头文件:
#include - 特点:固定大小的位序列
- 常用方法:
set(),reset(),flip(),test()count(),size(),any(),none()to_ulong(),to_string()
11. array(静态数组)
- 头文件:
#include - 特点:固定大小,支持STL接口
- 常用方法:
at(),front(),back(),fill()begin(),end(),size(),empty()
12. tuple(元组)
- 头文件:
#include - 特点:可存储多个不同类型的值
- 常用方法:
get<>()访问元素tie()解包make_tuple()构造
- 头文件:
#include - 特点:
- 双向链表结构,支持前后双向遍历
- 在任何位置插入删除都是 O(1) 时间复杂度
- 不支持随机访问(不能通过下标访问)
- 插入删除不会使迭代器失效
- 常用方法:
push_front()前插push_back()尾插pop_front()前删pop_back()尾删insert()指定位置插入erase()指定位置删除remove()按值删除remove_if()// 按值删除sort()排序merge()合并reverse()反转splice()转移元素到另一个listunique()删除连续重复元素
- 头文件:
#include - 特点:
- 双端队列,支持前后快速插入删除
- 支持随机访问(可以通过下标访问)
- 内部采用分段连续空间,比vector在头部插入更高效
- 扩容时不需要移动所有元素
- 常用方法:
push_front()、pop_front()前端操作push_back()、pop_back()后端操作insert()、erase()指定位置插入删除at()、operator[]随机访问clear()、resize()清空和调整大小
🔹 二、常用 STL 算法函数(Algorithms)
1. 排序与查找
sort(beg, end)stable_sort(beg, end)nth_element(beg, nth, end)lower_bound(beg, end, val)upper_bound(beg, end, val)binary_search(beg, end, val)
2. 最值
max_element(beg, end)min_element(beg, end)max(a, b),min(a, b)minmax(a, b)
3. 遍历与操作
for_each(beg, end, func)transform(beg, end, dest, func)fill(beg, end, val)iota(beg, end, start_val)
4. 排列
next_permutation(beg, end)prev_permutation(beg, end)
5. 集合操作
set_union()set_intersection()set_difference()
6. 其他常用
reverse(beg, end)__gcd(a, b)最大公约数random_shuffle(beg, end)(C++14 已弃用,建议用shuffle)unique(beg, end)accumulate(beg, end, init)__lg(x):返回 log2(x) 的整数部分__builtin_popcount(x):统计二进制中1的个数__builtin_ctz(x):统计末尾0的个数__builtin_clz(x):统计前导0的个数
对应的代码样例
🔹 Vector(动态数组)
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;int main() {// 初始化vector<int> v = {3, 1, 4, 1, 5, 9, 2, 6};// 添加元素v.push_back(8);v.insert(v.begin() + 2, 7); // 在索引2处插入7// 删除元素v.pop_back(); // 删除最后一个元素v.erase(v.begin() + 1); // 删除索引1处的元素// 排序sort(v.begin(), v.end());// 遍历输出cout << "Vector元素: ";for (auto x : v) {cout << x << " ";}cout << endl;// 输出: Vector元素: 1 2 3 4 5 6 7 9// 其他常用操作cout << "大小: " << v.size() << endl; // 8cout << "容量: " << v.capacity() << endl; // 16 (可能)cout << "第一个元素: " << v.front() << endl; // 1cout << "最后一个元素: " << v.back() << endl; // 9return 0;
}
🔹 Stack(栈)
#include <iostream>
#include <stack>
using namespace std;int main() {stack<int> s;// 入栈s.push(10);s.push(20);s.push(30);cout << "栈顶元素: " << s.top() << endl; // 30// 出栈s.pop();cout << "弹出后栈顶: " << s.top() << endl; // 20cout << "栈大小: " << s.size() << endl; // 2cout << "是否为空: " << s.empty() << endl; // 0 (false)// 遍历栈(通过出栈)cout << "栈内容: ";while (!s.empty()) {cout << s.top() << " ";s.pop();}cout << endl;// 输出: 栈内容: 20 10return 0;
}
🔹 Queue(队列)
#include <iostream>
#include <queue>
using namespace std;int main() {queue<int> q;// 入队q.push(10);q.push(20);q.push(30);cout << "队首: " << q.front() << endl; // 10cout << "队尾: " << q.back() << endl; // 30// 出队q.pop();cout << "出队后队首: " << q.front() << endl; // 20cout << "队列大小: " << q.size() << endl; // 2// 遍历队列cout << "队列内容: ";while (!q.empty()) {cout << q.front() << " ";q.pop();}cout << endl;// 输出: 队列内容: 20 30return 0;
}
🔹 Deque(双端队列)
#include <iostream>
#include <deque>
#include <algorithm>
using namespace std;int main() {// 初始化deque<int> dq = {2, 3, 4};// 前后插入dq.push_front(1); // 头部插入dq.push_back(5); // 尾部插入cout << "初始deque: ";for (auto x : dq) cout << x << " ";cout << endl;// 输出: 初始deque: 1 2 3 4 5// 随机访问cout << "下标访问 dq[2]: " << dq[2] << endl; // 3cout << "at方法访问 dq.at(3): " << dq.at(3) << endl; // 4// 前后删除dq.pop_front(); // 删除头部dq.pop_back(); // 删除尾部cout << "删除前后端后: ";for (auto x : dq) cout << x << " ";cout << endl;// 输出: 删除前后端后: 2 3 4// 中间插入auto it = dq.begin() + 1;dq.insert(it, 99); // 在位置1插入99cout << "中间插入99后: ";for (auto x : dq) cout << x << " ";cout << endl;// 输出: 中间插入99后: 2 99 3 4// 中间删除it = dq.begin() + 2;dq.erase(it); // 删除位置2的元素cout << "删除位置2后: ";for (auto x : dq) cout << x << " ";cout << endl;// 输出: 删除位置2后: 2 99 4// 批量插入dq.insert(dq.end(), {5, 6, 7});cout << "批量插入后: ";for (auto x : dq) cout << x << " ";cout << endl;// 输出: 批量插入后: 2 99 4 5 6 7// 调整大小dq.resize(10, 0); // 调整大小为10,新元素初始化为0cout << "调整大小后: ";for (auto x : dq) cout << x << " ";cout << endl;// 输出: 调整大小后: 2 99 4 5 6 7 0 0 0 0// 排序sort(dq.begin(), dq.end());cout << "排序后: ";for (auto x : dq) cout << x << " ";cout << endl;// 输出: 排序后: 0 0 0 0 2 4 5 6 7 99// 清空部分元素dq.erase(dq.begin() + 5, dq.end()); // 删除位置5到末尾cout << "删除部分后: ";for (auto x : dq) cout << x << " ";cout << endl;// 输出: 删除部分后: 0 0 0 0 2// 大小和容量信息cout << "deque大小: " << dq.size() << endl; // 5cout << "是否为空: " << dq.empty() << endl; // 0cout << "第一个元素: " << dq.front() << endl; // 0cout << "最后一个元素: " << dq.back() << endl; // 2// 清空dq.clear();cout << "清空后大小: " << dq.size() << endl; // 0cout << "是否为空: " << dq.empty() << endl; // 1return 0;
}
🔹 Map(映射)
#include <iostream>
#include <map>
using namespace std;int main() {map<string, int> score;// 插入元素score["Alice"] = 95;score["Bob"] = 87;score["Charlie"] = 92;score.insert({"David", 78});// 查找元素if (score.find("Alice") != score.end()) {cout << "Alice的成绩: " << score["Alice"] << endl; // 95}// 遍历mapcout << "所有学生成绩:" << endl;for (auto &[name, sc] : score) {cout << name << ": " << sc << endl;}/* 输出:Alice: 95Bob: 87Charlie: 92David: 78*/// 统计cout << "学生人数: " << score.size() << endl; // 4// 删除元素score.erase("Bob");cout << "删除Bob后人数: " << score.size() << endl; // 3return 0;
}
🔹 Set(集合)
#include <iostream>
#include <set>
#include <algorithm>
using namespace std;int main() {set<int> s = {5, 2, 8, 2, 1, 5}; // 重复元素自动去重// 插入元素s.insert(3);s.insert(7);// 遍历set(自动排序)cout << "Set元素: ";for (auto x : s) {cout << x << " ";}cout << endl;// 输出: Set元素: 1 2 3 5 7 8// 查找元素if (s.find(5) != s.end()) {cout << "5在集合中" << endl;}// 上下界查找auto it_low = s.lower_bound(3); // 第一个 >= 3 的元素auto it_up = s.upper_bound(6); // 第一个 > 6 的元素cout << ">=3的第一个元素: " << *it_low << endl; // 3cout << ">6的第一个元素: " << *it_up << endl; // 7cout << "集合大小: " << s.size() << endl; // 6return 0;
}
🔹 Priority Queue(优先队列)
#include <iostream>
#include <queue>
#include <vector>
using namespace std;int main() {// 默认大根堆priority_queue<int> max_heap;// 小根堆priority_queue<int, vector<int>, greater<int>> min_heap;// 添加元素vector<int> nums = {3, 1, 4, 1, 5, 9};for (int num : nums) {max_heap.push(num);min_heap.push(num);}// 大根堆输出(从大到小)cout << "大根堆: ";while (!max_heap.empty()) {cout << max_heap.top() << " ";max_heap.pop();}cout << endl;// 输出: 大根堆: 9 5 4 3 1 1// 小根堆输出(从小到大)cout << "小根堆: ";while (!min_heap.empty()) {cout << min_heap.top() << " ";min_heap.pop();}cout << endl;// 输出: 小根堆: 1 1 3 4 5 9return 0;
}
🔹 List(双向链表)
#include <iostream>
#include <list>
#include <algorithm>
using namespace std;int main() {// 初始化list<int> lst = {1, 2, 3, 4, 5};// 前后插入lst.push_front(0); // 头部插入lst.push_back(6); // 尾部插入cout << "初始链表: ";for (auto x : lst) cout << x << " ";cout << endl;// 输出: 初始链表: 0 1 2 3 4 5 6// 中间插入auto it = lst.begin();advance(it, 3); // 移动到第3个位置lst.insert(it, 99); // 在位置3插入99cout << "插入99后: ";for (auto x : lst) cout << x << " ";cout << endl;// 输出: 插入99后: 0 1 2 99 3 4 5 6// 删除元素lst.remove(3); // 删除所有值为3的元素lst.pop_front(); // 删除头部cout << "删除后: ";for (auto x : lst) cout << x << " ";cout << endl;// 输出: 删除后: 1 2 99 4 5 6// 排序(list有自己的sort方法)lst.sort();cout << "排序后: ";for (auto x : lst) cout << x << " ";cout << endl;// 输出: 排序后: 1 2 4 5 6 99// 反转lst.reverse();cout << "反转后: ";for (auto x : lst) cout << x << " ";cout << endl;// 输出: 反转后: 99 6 5 4 2 1// 合并两个listlist<int> lst2 = {10, 20, 30};lst.merge(lst2); // lst2会被清空cout << "合并后: ";for (auto x : lst) cout << x << " ";cout << endl;// 输出: 合并后: 10 20 30 99 6 5 4 2 1// splice操作:转移元素list<int> lst3 = {100, 200, 300};auto it2 = lst.begin();advance(it2, 2); // 移动到第2个位置lst.splice(it2, lst3); // 将lst3所有元素转移到lst的it2位置cout << "splice后: ";for (auto x : lst) cout << x << " ";cout << endl;// 输出: splice后: 10 20 100 200 300 30 99 6 5 4 2 1// 唯一化(需要先排序)lst.sort();lst.unique();cout << "排序去重后: ";for (auto x : lst) cout << x << " ";cout << endl;// 输出: 排序去重后: 1 2 4 5 6 10 20 30 99 100 200 300// 大小信息cout << "链表大小: " << lst.size() << endl; // 12cout << "是否为空: " << lst.empty() << endl; // 0cout << "第一个元素: " << lst.front() << endl; // 1cout << "最后一个元素: " << lst.back() << endl; // 300return 0;
}
🔹 String(字符串)
#include <iostream>
#include <string>
#include <algorithm>
using namespace std;int main() {string s1 = "Hello";string s2 = "World";// 字符串拼接string s3 = s1 + " " + s2;cout << "拼接: " << s3 << endl; // Hello World// 子串string sub = s3.substr(6, 5);cout << "子串: " << sub << endl; // World// 查找size_t pos = s3.find("World");if (pos != string::npos) {cout << "找到World在位置: " << pos << endl; // 6}// 替换s3.replace(6, 5, "C++");cout << "替换后: " << s3 << endl; // Hello C++// 大小写转换string s4 = "AbCdEf";transform(s4.begin(), s4.end(), s4.begin(), ::tolower);cout << "转小写: " << s4 << endl; // abcdeftransform(s4.begin(), s4.end(), s4.begin(), ::toupper);cout << "转大写: " << s4 << endl; // ABCDEF// 字符串转数字string num_str = "12345";int num = stoi(num_str);cout << "字符串转数字: " << num + 1 << endl; // 12346return 0;
}
🔹 常用算法函数
#include <iostream>
#include <vector>
#include <algorithm>
#include <numeric>
using namespace std;int main() {vector<int> v = {3, 1, 4, 1, 5, 9, 2, 6};// 排序sort(v.begin(), v.end());cout << "排序后: ";for (auto x : v) cout << x << " "; // 1 1 2 3 4 5 6 9cout << endl;// 反转reverse(v.begin(), v.end());cout << "反转后: ";for (auto x : v) cout << x << " "; // 9 6 5 4 3 2 1 1cout << endl;// 累加int sum = accumulate(v.begin(), v.end(), 0);cout << "总和: " << sum << endl; // 31// 查找最大最小值auto max_it = max_element(v.begin(), v.end());auto min_it = min_element(v.begin(), v.end());cout << "最大值: " << *max_it << endl; // 9cout << "最小值: " << *min_it << endl; // 1// 去重(需要先排序)sort(v.begin(), v.end());auto last = unique(v.begin(), v.end());v.erase(last, v.end());cout << "去重后: ";for (auto x : v) cout << x << " "; // 1 2 3 4 5 6 9cout << endl;// 二分查找if (binary_search(v.begin(), v.end(), 5)) {cout << "找到5了!" << endl;}// 填充vector<int> v2(5);fill(v2.begin(), v2.end(), 7);cout << "填充后: ";for (auto x : v2) cout << x << " "; // 7 7 7 7 7cout << endl;return 0;
}
🔹 Bitset(位集)
#include <iostream>
#include <bitset>
using namespace std;int main() {bitset<8> bits("11001100");cout << "原始位: " << bits << endl; // 11001100// 设置位bits.set(0); // 设置第0位为1cout << "设置第0位: " << bits << endl; // 11001101// 重置位bits.reset(3); // 设置第3位为0cout << "重置第3位: " << bits << endl; // 11000101// 翻转位bits.flip(2);cout << "翻转第2位: " << bits << endl; // 11000001// 统计1的个数cout << "1的个数: " << bits.count() << endl; // 4// 测试某位cout << "第1位是: " << bits.test(1) << endl; // 0// 所有位操作cout << "所有位为1: " << bits.all() << endl; // 0cout << "有位为1: " << bits.any() << endl; // 1cout << "没有位为1: " << bits.none() << endl; // 0return 0;
}
这些样例代码涵盖了STL的主要容器和算法函数,可以直接编译运行。
每个示例都包含了详细的注释和预期的输出结果。
