初学STL不会使用?我来教你!
2025-05-27 12:34:08
发布于:重庆
前言
STL,即标准模板库。标准模板库是一个C软件库,大量影响了C标准程序库但并非是其的一部分。本文主要讲解标准模板库中的 STL容器。其可以帮助你更好、更方便的写题。
Ⅰ、vector
vecotr,是动态数组,与普通数组的主要区别是可以动态修改数组长度,我们可以通过以下方式定义一个 vector 数组:
vector<int> adj(300);//定义一个长度为300的动态数组adj
需要注意的是,vector 的大小跟普通数组一样,下标从 开始。
vector 的动态修改数组长度 功能十分好用,很多时候我们不能提前开好那么大的空间。尽管我们能知道数据总量在空间允许的级别,但是单份数据还可能非常大,这种时候我们就需要 vector 来把内存占用量控制在合适的范围内。vector 还支持动态扩容,在内存非常紧张的时候这个特性就能派上用场了。
vector 基本可以代替我们的普通数组,以下是一些主要操作说明:
vector<int> adj;//定义长度为0的整形数组adj
adj.push_back(1);//在数组的下一项插入1
adj.push_back(3);//在数组的下一项插入1
adj.push_back(2);//在数组的下一项插入1
cout << adj[0] << endl;//可以像普通数组一样正常调用
sort(adj.begin(),adj.end());//排序
if(adj.empty()) cout << "empty!\n";//判断是否为空
else cout << "not empty!\n";
cout << adj.size() << endl;//输出adj的元素数量
for(auto i:adj) cout << i << " ";//遍历并输出adj数组
adj.clear();//可以快速清除数组
此时应该输出:
1
not empty!
3
1 2 3
Ⅱ、set
set 是关联容器,含有键值类型对象的已排序集,搜索、移除和插入拥有对数复杂度。set 内部通常采用 红黑树 实现。平衡二叉树 的特性使得 set 非常适合处理需要同时兼顾查找、插入与删除的情况。
set 比较常用的功能是查重。set 可以自动查重并排序,特别的是,你可以使用 multiset 完成可重复的有序 set,或使用 unordered_set 完成可重复的无序 set。
以下是一些比较常用的 set 用法:
set<int> s;//定义一个整数类型的set
s.insert(1);//在s中插入一个1
s.insert(1);//在s中插入一个1
s.insert(2);//在s中插入一个2
s.insert(3);//在s中插入一个3
cout << s.count(1) << endl;//输出s中1的数量,但由于有查重,所以实际上只有1或0
s.erase(2);//删除元素2
cout << s.count(2) << endl;//输出s中2的数量,但由于有查重,所以实际上只有1或0
auto l=s.lower_bound(2);//第一个≥2的元素迭代器
auto r=s.upper_bound(2);//第一个>2的元素迭代器
cout << s.size() << endl;//s的数据数量
for(auto i:s) cout << i << " ";//遍历输出s
不出意外应该输出以下内容:
1
0
2
1 3
set 可以方便的进行查重、查找等操作,并且时间复杂度并不高。
Ⅲ、map
map 是C++标准模板库中的一个关联容器,它存储键值对,并提供基于键的高效查找功能,和set一样,它可以自动排序和查重。插入、删除、查找的时间复杂度仅为O(log n),空间复杂度:O(n),是非常好用的STL容器。相同的,和set一样,你可以使用 multimap 完成可重复的有序 map,或使用 unordered_map 完成可重复的无序 map。
map 可以看作一个支持多种类型下标的数组,你可以用它来完成桶排序,并且可以让出了int以外类型来当作下标。
map<string,int> mp;//定义string到int的映射
mp["yulin"]=11;//定义
mp["ruiqi"]=10;
mp.insert({"yihan",12});//你也可以直接进行insert
mp.erase("yihan");//删除元素
cout << "yulin's age: " << mp["yulin"] << endl;//调用
for(auto i:mp) cout << i.first << ": " << i.second << endl;//遍历
auto i=mp.find("ruiqi");//查找元素
输出:
yulin's age: 11
ruiqi: 10
yulin: 11
Ⅳ、stack
stack 是C++标准模板库中的一种容器适配器,它提供后进先出(LIFO)的数据结构,限制了元素的访问方式,仅允许在栈顶进行插入和删除操作。
以下是一些常用的 stack 操作示例:
stack<int> stk; // 定义一个整数类型的栈
stk.push(1); // 压入元素1
stk.push(2); // 压入元素2
stk.push(3); // 压入元素3
cout << "Top element: " << stk.top() << endl; // 输出栈顶元素
stk.pop(); // 弹出栈顶元素
cout << "Top element after pop: " << stk.top() << endl; // 输出新的栈顶元素
cout << "Stack size: " << stk.size() << endl; // 输出栈的大小
if (stk.empty()) cout << "Stack is empty!\n"; // 判断栈是否为空
else cout << "Stack is not empty!\n";
输出结果:
Top element: 3
Top element after pop: 2
Stack size: 2
Stack is not empty!
stack 的主要特点:
- 后进先出(LIFO):最后压入的元素最先弹出。
- 限制访问:只能访问栈顶元素,不能直接访问中间或底部元素。
- 高效操作:压栈和弹栈的时间复杂度为 O(1)。
Ⅴ、queue
这玩意我们一般叫缺缺
queue 是C++标准模板库中的一种容器适配器,它提供先进先出(FIFO)的数据结构。queue 通常基于 deque 或 list 实现,但限制了元素的访问方式,仅允许在队尾插入(push)和在队头删除(pop)。
基本操作示例
queue<int> q; // 定义一个整数类型的队列
q.push(1); // 入队元素1
q.push(2); // 入队元素2
q.push(3); // 入队元素3
cout << "Front element: " << q.front() << endl; // 输出队头元素
cout << "Back element: " << q.back() << endl; // 输出队尾元素
q.pop(); // 出队(删除队头元素)
cout << "Front element after pop: " << q.front() << endl; // 输出新的队头元素
cout << "Queue size: " << q.size() << endl; // 输出队列的大小
if (q.empty()) cout << "Queue is empty!\n"; // 判断队列是否为空
else cout << "Queue is not empty!\n";
输出结果:
Front element: 1
Back element: 3
Front element after pop: 2
Queue size: 2
Queue is not empty!
特点
- 先进先出(FIFO):先入队的元素先出队。
- 限制访问:只能访问队头和队尾元素,不能直接访问中间元素。
- 高效操作:入队和出队的时间复杂度为 O(1)。
如果需要自动排序的队列,可以使用 priority_queue(优先队列),它基于堆实现,默认是大根堆,队头元素始终是最大的。
priority_queue<int> pq; // 大根堆
pq.push(3);
pq.push(1);
pq.push(2);
cout << "Top element: " << pq.top() << endl; // 输出堆顶元素(最大值)
pq.pop();
cout << "Top element after pop: " << pq.top() << endl;
输出:
Top element: 3
Top element after pop: 2
queue 是处理顺序性任务的强大工具,而 priority_queue 则适用于需要动态获取最值的场景。
Ⅵ、string
string 是C++标准模板库中提供的字符串类型,比C风格的字符数组(char[]
)更安全、更易用。它支持动态内存管理,并提供了丰富的字符串操作方法,如拼接、查找、替换、子串提取等。
常用操作:
string s1; // 默认初始化,空字符串
string s2 = "Hello"; // 直接赋值
string s3("World"); // 构造函数初始化
string s4(5, 'A'); // 生成 "AAAAA"
string s5(s2); // 拷贝构造,s5 = "Hello"
string s = "Hello";
cout << s[0]; // 'H'(访问第一个字符)
cout << s.at(1); // 'e'(更安全)
string s1 = "Hello", s2 = "World";
string s3 = s1 + " " + s2; // "Hello World"
s1.append(s2); // s1 = "HelloWorld"
string a = "abc", b = "def";
if (a < b) cout << "a is lex smaller than b";
string s = "HelloWorld";
string sub = s.substr(5, 5); // "World"(从第5个字符取5个)
string s="Hello, C++!";
size_t pos=s.find("C++"); // 7
if (pos != string::npos) {
s.replace(pos, 3, "Python"); // "Hello, Python!"
}
string s = "Hello";
cout << s.size(); // 5
if (!s.empty()) cout << "Not empty!";
输入整行(含空格)
string line;
getline(cin, line); // 读取一行(包括空格)
string
提供了比C风格字符串更安全、更便捷的操作,适用于大多数字符串处理场景。它的动态内存管理避免了缓冲区溢出的风险,同时丰富的API极大提高了开发效率。
Ⅶ、pair
1. 是什么?
- 存两个值的小容器
- 常用在需要返回两个值的地方
基本用法
pair<int,string> p={1,"apple"}; // 创建
cout << p.first; // 取第一个值 → 1
cout << p.second; // 取第二个值 → "apple"
返回两个值
pair<int,int> div(int a,int b)
{
return {a/b,a%b}; // 商和余数
}
当map用
map<string, pair<int, double>> grades;
grades["yulinOvO"]={90,85.5};
排序数组
vector<pair<int, string>> v = {{3,"C"}, {1,"A"}, {2,"B"}};
sort(v.begin(), v.end()); // 按第一个值排序
pair可以当一个简化版的struct使用,但是更方便。
总结
STL真方便!
这里空空如也
有帮助,赞一个