STL浅析

最近在敲代码的时候,遇到了一些STL知识,感觉比较杂乱,所以在此利用已有资料,综合一下自己的理解发布本篇博客。

C++ STL之动态数组vector(⽮量)

C语⾔⾥⾯⽤ int arr[] 定义数组,它的缺点是数组的⻓度不能随⼼所欲的改变,⽽C++⾥⾯有⼀个能完全替代数组的动态数组 vector (有的书⾥⾯把它翻译成⽮量, vector 本身就是⽮量、向量的意思,但是叫做动态数组或者不定⻓数组我觉得更好理解,绝⼤多数中⽂⽂档中⼀般不翻译直接叫它vector~),它能够在运⾏阶段设置数组的⻓度、在末尾增加新的数据、在中间插⼊新的值、⻓度任意被改变,很好⽤~它在头⽂件 vector ⾥⾯,也在命名空间 std ⾥⾯,所以使⽤的时候要引⼊头⽂件 #include <vector> 和 using namespace std; vector 、 stack 、 queue 、 map 、 set 这些在C++中都叫做容器,这些容器的⼤⼩都可以⽤ .size()获取到,就像 string s 的⻓度⽤ s.length() 获取⼀样~( string 其实也可以⽤ s.size() ,不过对于vector 、 stack 、 queue 、 map 、 set 这样的容器我们⼀般讨论它的⼤⼩ size ,字符串⼀般讨论它的⻓度 length ~其实 string ⾥⾯的 size 和 length 两者是没有区别、可以互换使⽤的。

#include <iostream>

#include <vector>

using namespace std;

int main()

{

vector<int> v1; // 定义⼀个vector v1,定义的时候没有分配⼤⼩

cout << v1.size(); // 输出vector v1的⼤⼩,此处应该为0

return 0;

}

vector 可以⼀开始不定义⼤⼩,之后⽤ resize ⽅法分配⼤⼩,也可以⼀开始就定义⼤⼩,之后还可以对它插⼊删除动态改变它的⼤⼩~⽽且不管在 main 函数⾥还是在全局中定义,它都能够直接将所有的值初始化为0(不⽤显式地写出来,默认就是所有的元素为0),再也不⽤担⼼C语⾔⾥⾯出现的那种 int arr[10]; 结果忘记初始化为0导致的各种bug啦~

vector<int> v(10); // 直接定义⻓度为10的int数组,默认这10个元素值都为0,// 或者

vector<int> v1;

v1.resize(8); //先定义⼀个vector变量v1,然后将⻓度resize为8,默认这8个元素都是0

// 在定义的时候就可以对vector变量进⾏初始化

vector<int> v3(100, 9);// 把100⻓度的数组中所有的值都初始化为9

// 访问的时候像数组⼀样直接⽤[]下标访问即可~(也可以⽤迭代器访问~)

v[1] = 2;

cout << v[0];

不管是 vector 、 stack 、 queue 、 map 还是 set 都有很多好⽤的⽅法,这些⽅法都可以在www.cplusplus.com官⽅⽹站中直接查询官⽅⽂档,上⾯有⽅法的讲解和代码示例~官⽅⽂档是刷题时候必不可少的好伙伴~(如果你⽤的是 Mac OS 系统,下载软件 Dash 然后在⾥⾯下载好C++,平时查⽂档会更⽅便。)Windows 下的离线⽂档浏览器 Zeal (https://zealdocs.org/),和 Dash 的功能⼀样,使⽤ Windows 的⼩伙伴可以下载 Zeal 看离线官⽅⽂档~

⽐如进⼊官⽹搜索 vector ,就会出现 vector 拥有的所有⽅法,点进去⼀个⽅法就能看到这个⽅法的详细解释和代码示例~当然我们平时写算法⽤不到那么多⽅法啦,只有⼏个是常⽤的~以下是⼀些常⽤的 vector ⽅法:

#include <iostream>

#include <vector>

using namespace std;

int main()

{

vector<int> a; // 定义的时候不指定vector的⼤⼩

cout << a.size() << endl; // 这个时候size是0

for (int i = 0; i < 5; i++) {

a.push_back(i); // 在vector a的末尾添加⼀个元素i

a.pop_back(i);

a.front();

}

cout << a.size() << endl; // 此时会发现a的size变成了5

vector<int> b(10); // 定义的时候指定vector的⼤⼩,默认b⾥⾯元素都是0

cout << b.size() << endl;

for (int i = 0; i < b.size(); i++) {

b[i] = 10;

}

for (int i = 0; i < b.size(); i++) {

cout << b[i] << " ";

}

cout << endl;

vector<int> c(20, 2); // 定义的时候指定vector的⼤⼩并把所有的元素赋⼀个指定的值

for (int i = 0; i < c.size(); i++) {

cout << c[i] << " ";

}

cout << endl;

for (auto it = c.begin(); it != c.end(); it++) { // 使⽤迭代器的⽅式访问vector

cout << *it << " ";

}

return 0;

}

容器 vector 、 set 、 map 这些遍历的时候都是使⽤迭代器访问的, c.begin() 是⼀个指针,指向容器的第⼀个元素, c.end() 指向容器的最后⼀个元素的后⼀个位置,所以迭代器指针 it 的for循环判断条件是 it != c.end()

再重复⼀遍~ c.end() 指向容器的最后⼀个元素的后⼀个位置,这是⼀个重点和难点,画个图加深⼀下大家的记忆:

访问元素的值要对 it 指针取值,要在前⾯加星号!所以是 cout << *it;这⾥的auto相当于 vector<int>::iterator 的简写

C++ STL之集合set的使⽤

set 是集合,⼀个 set ⾥⾯的各元素是各不相同的,所以set有去重效果,⽽且 set 会按照元素进⾏从⼩到⼤排序~以下是 set 的常⽤⽤法:

#include <iostream>

#include <set>

using namespace std;

int main(void)

{

set<int> s; // 定义⼀个空集合s

s.insert(1); // 向集合s⾥⾯插⼊⼀个1

cout << *(s.begin()) << endl; // 输出集合s的第⼀个元素 (前⾯的星号表示要对指针取值)

for (int i = 0; i < 6; i++) {

s.insert(i); // 向集合s⾥⾯插⼊i

}

for (auto it = s.begin(); it != s.end(); it++) { // ⽤迭代器遍历集合s⾥⾯的每⼀个元素

cout << *it << " ";

}

cout << endl << (s.find(2) != s.end()) << endl; // 查找集合s中的值,如果结果等于s.end()表示未找到 (因为s.end()表示s的最后⼀个元素的下⼀个元素所在的位置)

cout << (s.find(10) != s.end()) << endl; // s.find(10) != s.end()表示能找到10这个元素

s.erase(1); // 删除集合s中的1这个元素

cout << (s.find(1) != s.end()) << endl; // 这时候元素1就应该找不到啦~

return 0;

C++ STL之映射map的使⽤

map 是键值对,⽐如⼀个⼈名对应⼀个学号,就可以定义⼀个字符串 string 类型的⼈名为“键”,学号 int 类型为“值”,如 map<string, int> m; 当然键、值也可以是其它变量类型。 map 会⾃动将所有的键值对按照键从⼩到⼤排序, map 使⽤时的头⽂件 #include <map> 以下是 map 中常⽤的⽅法:

#include <iostream>

#include <map>

#include <string>

using namespace std;

int main(void)

{

map<string, int> m; // 定义⼀个空的map m,键是string类型的,值是int类型的

m["hello"] = 2; // 将key为"hello", value为2的键值对(key-value)存⼊map中

cout << m["hello"] << endl; // 访问map中key为"hello"的value, 如果key不存在,则返回0

cout << m["world"] << endl;

m["world"] = 3; // 将"world"键对应的值修改为3

m[","] = 1; // 设⽴⼀组键值对,键为"," 值为1

// ⽤迭代器遍历,输出map中所有的元素,键⽤it->first获取,值⽤it->second获取

for (auto it = m.begin(); it != m.end(); it++) {

cout << it->first << " " << it->second << endl;//m[it->first]=it->second;

}

// 访问map的第⼀个元素,输出它的键和值

cout << m.begin()->first << " " << m.begin()->second << endl;

// 访问map的最后⼀个元素,输出它的键和值

cout << m.rbegin()->first << " " << m.rbegin()->second << endl;

//逆序遍历

map<string, int>::reverse_iterator it;//这里用auto如何取代暂未考虑

for (it = m.rbegin(); it != m.rend(); it++) {

cout << it->first << " " << it->second << endl; 

// 输出map的元素个数

cout << m.size() << endl;

return 0;

}

C++ STL之栈stack的使⽤

栈 stack 在头⽂件 #include <stack> 中,是数据结构⾥⾯的栈~以下是常⽤⽤法:

#include <iostream>

#include <stack>

using namespace std;

int main(void)

{

stack<int> s; // 定义⼀个空栈s

for (int i = 0; i < 6; i++) {

s.push(i); // 将元素i压⼊栈s中

}

cout << s.top() << endl; // 访问s的栈顶元素

cout << s.size() << endl; // 输出s的元素个数

s.pop(); // 移除栈顶元素

return 0;

}

C++ STL之队列queue的使⽤

队列 queue 在头⽂件 #include <queue> 中,是数据结构⾥⾯的队列~以下是常⽤⽤法:

#include <iostream>

#include <queue>

using namespace std;

int main(void)

{

queue<int> q; // 定义⼀个空队列q

for (int i = 0; i < 6; i++) {

q.push(i); // 将i的值依次压⼊队列q中

}

cout << q.front() << " " << q.back() << endl; // 访问队列的队⾸元素和队尾元素

cout << q.size() << endl; // 输出队列的元素个数

q.pop(); // 移除队列的队⾸元素

return 0;

}

C++ STL之unordered_map和unordered_set的使⽤

unordered_map 在头⽂件 #include <unordered_map> 中, unordered_set 在头⽂件 #include<unordered_set> 中~

unordered_map 和 map (或者 unordered_set 和 set )的区别是, map 会按照键值对的键 key 进⾏排序( set ⾥⾯会按照集合中的元素⼤⼩进⾏排序,从⼩到⼤顺序),⽽ unordered_map (或者 unordered_set )省去了这个排序的过程,如果偶尔刷题时候⽤ map 或者 set 超时了,可以考虑⽤ unordered_map (或者 unordered_set )缩短代码运⾏时间、提⾼代码效率~⾄于⽤法和map 、 set 是⼀样的~

C++中list用法详解_Donny-You的博客-CSDN博客_c++ list

C++中empty()作为判断容器是否为空的函数;

网上还有许多比本人这个更精简且容易理解的STL,大家可自行查阅

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

星河欲转。

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值