前言:STL(Standard Template Library)宛如一座宝藏库,为开发者们提供了高效、灵活且功能强大的组件,极大提升了代码的开发效率与质量。
目录
一、 STL 简介
STL,即标准模板库(Standard Template Library),是 C++ 中一个功能强大且被广泛使用的工具集。它就像一个精巧的工具箱,为开发者提供了大量预先构建好的数据结构和算法,极大简化了编程工作。STL 不仅能提高代码的可读性,还能让程序运行得更快、更高效。换句话说,它就像编程世界里的 “瑞士军刀”,是每个 C++ 程序员都应该掌握的利器。接下来,我将带你一步步走进 STL 的世界,从最基础的概念开始,逐渐深入到更复杂的部分。
二、容器
STL 的基石
容器,顾名思义,就是用来存储和管理数据的工具。STL 提供了多种容器,每种都有其独特的优势和适用场景,下面我将逐一介绍。
(一)序列容器:动态数据存储的首选
-
vector :动态数组,支持随机访问元素
#include <iostream>
#include <vector>
using namespace std;
int main() {
vector<int> vec;
vec.push_back(10);
vec.push_back(20);
vec.push_back(30);
cout << "vector 大小:" << vec.size() << endl;
for (int i = 0; i < vec.size(); i++) {
cout << vec[i] << " ";
}
cout << endl;
vec.pop_back();
cout << "删除末尾元素后,vector 大小:" << vec.size() << endl;
if (vec.empty()) {
cout << "vector 为空" << endl;
} else {
cout << "vector 不为空" << endl;
}
vec.clear();
cout << "清空后,vector 大小:" << vec.size() << endl;
return 0;
}
输出结果为:
vector 大小:3
10 20 30
删除末尾元素后,vector 大小:2
vector 不为空
清空后,vector 大小:0
-
list :双向链表,适合频繁在中间插入和删除元素
#include <iostream>
#include <list>
using namespace std;
int main() {
list<int> lst;
lst.push_back(10);
lst.push_back(20);
lst.push_front(5);
for (list<int>::iterator it = lst.begin(); it != lst.end(); it++) {
cout << *it << " ";
}
cout << endl;
lst.insert(lst.begin(), 3);
lst.insert(lst.end(), 25);
for (list<int>::iterator it = lst.begin(); it != lst.end(); it++) {
cout << *it << " ";
}
cout << endl;
lst.erase(lst.begin());
lst.pop_back();
for (list<int>::iterator it = lst.begin(); it != lst.end(); it++) {
cout << *it << " ";
}
cout << endl;
return 0;
}
输出结果为:
5 10 20
3 5 10 20 25
5 10 20
-
deque :双端队列,允许在两端快速插入和删除元素
#include <iostream>
#include <deque>
using namespace std;
int main() {
deque<int> dq;
dq.push_back(10);
dq.push_back(20);
dq.push_front(5);
for (deque<int>::iterator it = dq.begin(); it != dq.end(); it++) {
cout << *it << " ";
}
cout << endl;
dq.pop_front();
dq.pop_back();
for (deque<int>::iterator it = dq.begin(); it != dq.end(); it++) {
cout << *it << " ";
}
cout << endl;
return 0;
}
输出结果为:
5 10 20
10
(二)关联容器:基于排序的高效数据存储
-
set :基于排序的集合,不允许有重复元素
#include <iostream>
#include <set>
using namespace std;
int main() {
set<int> st;
st.insert(10);
st.insert(20);
st.insert(5);
st.insert(10);
for (set<int>::iterator it = st.begin(); it != st.end(); it++) {
cout << *it << " ";
}
cout << endl;
st.erase(10);
for (set<int>::iterator it = st.begin(); it != st.end(); it++) {
cout << *it << " ";
}
cout << endl;
if (st.find(5) != st.end()) {
cout << "找到元素 5" << endl;
} else {
cout << "未找到元素 5" << endl;
}
if (st.find(10) != st.end()) {
cout << "找到元素 10" << endl;
} else {
cout << "未找到元素 10" << endl;
}
return 0;
}
输出结果为:
5 10 20
5 20
找到元素 5
未找到元素 10
-
map :基于排序的键值对集合,键是唯一的
#include <iostream>
#include <map>
using namespace std;
int main() {
map<string, int> mp;
mp.insert(pair<string, int>("apple", 10));
mp.insert(pair<string, int>("banana", 20));
mp["orange"] = 30;
for (map<string, int>::iterator it = mp.begin(); it != mp.end(); it++) {
cout << it->first << ": " << it->second << endl;
}
mp.erase("banana");
for (map<string, int>::iterator it = mp.begin(); it != mp.end(); it++) {
cout << it->first << ": " << it->second << endl;
}
map<string, int>::iterator it = mp.find("apple");
if (it != mp.end()) {
cout << "找到键 " << it->first << ",对应的值为 " << it->second << endl;
} else {
cout << "未找到键 apple" << endl;
}
if (mp.find("banana") != mp.end()) {
cout << "找到键 banana" << endl;
} else {
cout << "未找到键 banana" << endl;
}
return 0;
}
输出结果为:
apple: 10
banana: 20
orange: 30
apple: 10
orange: 30
找到键 apple,对应的值为 10
未找到键 banana
(三)无序关联容器:基于哈希表的快速数据存储
-
unordered_set :基于哈希表的集合,允许有重复元素
#include <iostream>
#include <unordered_set>
using namespace std;
int main() {
unordered_set<int> ust;
ust.insert(10);
ust.insert(20);
ust.insert(5);
ust.insert(10);
for (unordered_set<int>::iterator it = ust.begin(); it != ust.end(); it++) {
cout << *it << " ";
}
cout << endl;
ust.erase(10);
for (unordered_set<int>::iterator it = ust.begin(); it != ust.end(); it++) {
cout << *it << " ";
}
cout << endl;
if (ust.find(5) != ust.end()) {
cout << "找到元素 5" << endl;
} else {
cout << "未找到元素 5" << endl;
}
if (ust.find(10) != ust.end()) {
cout << "找到元素 10" << endl;
} else {
cout << "未找到元素 10" << endl;
}
return 0;
}
输出结果为:
5 10 20
5 20
找到元素 5
未找到元素 10
-
unordered_map :基于哈希表的键值对集合,键是唯一的
#include <iostream>
#include <unordered_map>
using namespace std;
int main() {
unordered_map<string, int> ump;
ump.insert(pair<string, int>("apple", 10));
ump.insert(pair<string, int>("banana", 20));
ump["orange"] = 30;
for (unordered_map<string, int>::iterator it = ump.begin(); it != ump.end(); it++) {
cout << it->first << ": " << it->second << endl;
}
ump.erase("banana");
for (unordered_map<string, int>::iterator it = ump.begin(); it != ump.end(); it++) {
cout << it->first << ": " << it->second << endl;
}
unordered_map<string, int>::iterator it = ump.find("apple");
if (it != ump.end()) {
cout << "找到键 " << it->first << ",对应的值为 " << it->second << endl;
} else {
cout << "未找到键 apple" << endl;
}
if (ump.find("banana") != ump.end()) {
cout << "找到键 banana" << endl;
} else {
cout << "未找到键 banana" << endl;
}
return 0;
}
输出结果为:
orange: 30
apple: 10
banana: 20
orange: 30
apple: 10
找到键 apple,对应的值为 10
未找到键 banana
三、迭代器
容器的导航工具
迭代器就像容器的 “导游”,它可以帮助我们访问容器中的元素。有了迭代器,我们可以轻松地遍历容器,对元素进行操作。
-
使用迭代器遍历容器
#include <iostream>
#include <vector>
using namespace std;
int main() {
vector<int> vec = {1, 2, 3, 4, 5};
for (vector<int>::iterator it = vec.begin(); it != vec.end(); it++) {
cout << *it << " ";
}
cout << endl;
for (vector<int>::iterator it = vec.begin(); it != vec.end(); it++) {
*it *= 2;
}
for (vector<int>::iterator it = vec.begin(); it != vec.end(); it++) {
cout << *it << " ";
}
cout << endl;
cout << "vector 中索引为 2 的元素:" << vec[2] << endl;
cout << "vector 中迭代器指向索引为 3 的元素:" << *(vec.begin() + 3) << endl;
return 0;
}
输出结果为:
1 2 3 4 5
2 4 6 8 10
vector 中索引为 2 的元素:6
vector 中迭代器指向索引为 3 的元素:8
四、算法
数据处理的瑞士军刀
STL 的算法库提供了大量用于处理容器中数据的函数,它们就像瑞士军刀一样,功能丰富且强大。
(一)排序算法
-
sort() :对容器中的元素进行排序
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
int main() {
vector<int> vec = {5, 3, 8, 1, 6};
cout << "排序前:";
for (int i = 0; i < vec.size(); i++) {
cout << vec[i] << " ";
}
cout << endl;
sort(vec.begin(), vec.end());
cout << "升序排序后:";
for (int i = 0; i < vec.size(); i++) {
cout << vec[i] << " ";
}
cout << endl;
sort(vec.begin(), vec.end(), greater<int>());
cout << "降序排序后:";
for (int i = 0; i < vec.size(); i++) {
cout << vec[i] << " ";
}
cout << endl;
return 0;
}
输出结果为:
排序前:5 3 8 1 6
升序排序后:1 3 5 6 8
降序排序后:8 6 5 3 1
-
stable_sort() :保持相等元素相对顺序的排序
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
int main() {
vector<int> vec = {5, 3, 8, 1, 6, 5, 3};
cout << "排序前:";
for (int i = 0; i < vec.size(); i++) {
cout << vec[i] << " ";
}
cout << endl;
stable_sort(vec.begin(), vec.end());
cout << "稳定升序排序后:";
for (int i = 0; i < vec.size(); i++) {
cout << vec[i] << " ";
}
cout << endl;
stable_sort(vec.begin(), vec.end(), greater<int>());
cout << "稳定降序排序后:";
for (int i = 0; i < vec.size(); i++) {
cout << vec[i] << " ";
}
cout << endl;
return 0;
}
输出结果为:
排序前:5 3 8 1 6 5 3
稳定升序排序后:1 3 3 5 5 6 8
稳定降序排序后:8 6 5 5 3 3 1
(二)搜索算法
-
find() :在容器中查找指定值的元素
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
int main() {
vector<int> vec = {5, 3, 8, 1, 6};
vector<int>::iterator it = find(vec.begin(), vec.end(), 8);
if (it != vec.end()) {
cout << "找到元素 8,位置在索引:" << distance(vec.begin(), it) << endl;
} else {
cout << "未找到元素 8" << endl;
}
it = find(vec.begin(), vec.end(), 10);
if (it != vec.end()) {
cout << "找到元素 10,位置在索引:" << distance(vec.begin(), it) << endl;
} else {
cout << "未找到元素 10" << endl;
}
return 0;
}
输出结果为:
找到元素 8,位置在索引:2
未找到元素 10
-
binary_search() :在已排序的容器中查找指定值的元素
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
int main() {
vector<int> vec = {1, 3, 5, 6, 8};
if (binary_search(vec.begin(), vec.end(), 5)) {
cout << "找到元素 5" << endl;
} else {
cout << "未找到元素 5" << endl;
}
if (binary_search(vec.begin(), vec.end(), 10)) {
cout << "找到元素 10" << endl;
} else {
cout << "未找到元素 10" << endl;
}
return 0;
}
输出结果为:
找到元素 5
未找到元素 10
(三)数值计算
-
accumulate() :计算容器中元素的总和
#include <iostream>
#include <vector>
#include <numeric>
using namespace std;
int main() {
vector<int> vec = {5, 3, 8, 1, 6};
int sum = accumulate(vec.begin(), vec.end(), 0);
cout << "元素总和:" << sum << endl;
return 0;
}
输出结果为:
元素总和:23
-
inner_product() :计算两个容器的内积
#include <iostream>
#include <vector>
#include <numeric>
using namespace std;
int main() {
vector<int> vec1 = {1, 2, 3};
vector<int> vec2 = {4, 5, 6};
int inner = inner_product(vec1.begin(), vec1.end(), vec2.begin(), 0);
cout << "内积:" << inner << endl;
return 0;
}
输出结果为:
内积:32
五、STL 的优势
-
代码复用性高 :开发者无需重复编写常见的数据结构和算法代码,直接使用 STL 提供的现成功能,大大提高了开发效率,减少了代码冗余。
-
高效性 :STL 内部经过优化,许多算法和容器的实现都采用了高效的数据结构和算法策略,能够提供良好的性能表现,满足多数应用场景的需求。
-
易于维护和扩展 :由于 STL 的组件具有良好的封装性和一致性,代码更易于阅读、理解和维护。并且可以通过自定义容器、迭代器和算法来扩展 STL 的功能,以适应特定的项目要求。
总结
C++ STL 是 C++ 编程中不可或缺的一部分,它提供了丰富且强大的功能,能够帮助开发者高效地完成各种编程任务。从简单的容器使用到复杂的算法操作,STL 都有相应的解决方案。希望本文能帮助你更好地理解和掌握 C++ STL,提升你的编程能力。在后续的学习和实践中,你可以不断深入探索 STL 的更多细节和高级用法,充分发挥其潜力,编写出更加高效、简洁、健壮的代码。