[C++随笔录] vector使用

vector使用

通过上一篇文章 string的模拟实现, 其实我们就已经踏入了STL的门槛.

STL容器的大致用法是差不多的 ⇒ 那我们这篇博客就讲一点跟string类不一样的新颖的东西

初始化

跟string一样, vector可以采用下面的形式初始化

cpp 复制代码
// 默认空间, 默认初始化
vector<int> vec;

// 开10个空间, 初始化为系统默认
vector<int> vec(10);

// 开10个空间, 初始化为1
vector<int> vec(10, 1);

vector可以采用 迭代器区间初始化👇👇👇

  1. 采用同类型的迭代器区间
cpp 复制代码
vector<string> vs1;
vs1.push_back("hello world");

vector<string> vs2 (vs1.begin(), vs1.end());
for (auto e : vs2)
{
	cout << e << " ";
}
cout << endl;

*****
hello world
*****
  1. 采用不同类型的迭代器区间
cpp 复制代码
vector<char> vc(5, 'b');

vector<int> vs2(vc.begin(), vc.end());
for (auto e : vs2)
{
	cout << e << " ";
}
cout << endl;

*****
98 98 98 98 98
*****
  1. 采用数组
cpp 复制代码
int a[5] = { 1,2,3,4,5 };
vector<int> vi (a, a + sizeof(a) / sizeof(int));

for (auto e : vi)
{
	cout << e << " ";
}
cout << endl;

*****
1 2 3 4 5
*****

排序算法

vector容器本身是没有 sort算法的, 但是算法库中是有 sort算法的, 头文件是 <algorithm>

👇👇👇

cpp 复制代码
int a[8] = { 11,25,3,14,5, 6, 18,20 };
vector<int> vi (a, a + sizeof(a) / sizeof(int));

sort(vi.begin(), vi.end());

for (auto e : vi)
{
	cout << e << " ";
}
cout << endl;

*****
3 5 6 11 14 18 20 25
*****

发现, 默认是升序的, 那么如何进行降序呢?

cpp 复制代码
int a[8] = { 11,25,3,14,5, 6, 18,20 };
vector<int> vi (a, a + sizeof(a) / sizeof(int));

greater<int> gt; // greater<int> 仿函数对象
sort(vi.begin(), vi.end(), gt);

for (auto e : vi)
{
	cout << e << " ";
}
cout << endl;

*****
25 20 18 14 11 6 5 3
*****

int a[8] = { 11,25,3,14,5, 6, 18,20 };
vector<int> vi (a, a + sizeof(a) / sizeof(int));

less<int> l;
sort(vi.begin(), vi.end(), l);

for (auto e : vi)
{
	cout << e << " ";
}
cout << endl;

*****
3 5 6 11 14 18 20 25
*****

上面的 greaterless 是两个仿函数, int 是 模版参数

由于 sort是一个 函数模版 ⇒ 里面的参数是 对象

那么greater 和 less两个仿函数也要传两个对象过去, 即 gtl

⇒ 由此, 我们可以得出: sort函数默认里面放的是less仿函数的对象

由于里面传的是一个对象, 那么匿名对象也是可以的

其实, 我们也可以这样写👇👇👇

cpp 复制代码
int a[8] = { 11,25,3,14,5, 6, 18,20 };
vector<int> vi (a, a + sizeof(a) / sizeof(int));

sort(vi.begin(), vi.end(), greater<int> ());

for (auto e : vi)
{
	cout << e << " ";
}
cout << endl;

其实, 如果要排降序, 我们也可以抖个机灵反向迭代器

cpp 复制代码
int a[8] = { 11,25,3,14,5, 6, 18,20 };
vector<int> vi (a, a + sizeof(a) / sizeof(int));

sort(vi.rbegin(), vi.rend());

for (auto e : vi)
{
	cout << e << " ";
}
cout << endl;

*****
25 20 18 14 11 6 5 3
*****

reverse和resize

  1. reverse --- --- 开空间
  2. resize --- --- 开空间 + 初始化

基础不好的同学看到这里就有疑问了:

🗨️ reverse 和 resize 的功能重复了, 要一个就可以了! 开空间是最重要的, 那要一个reverse就可以. 初始化啥的, 我们后面自己弄就行了

  • 其实, 这个问题, 我们在 string的模拟实现 中就有答案!
    先看下面的一个例子👇👇👇
cpp 复制代码
vector<int> vec;
vec.reserve(10);

for (int i = 0; i < 10; i++)
{
	vec[i] = i;
}

*****
error
*****

这是因为 operator[] 的实现中, 我们有一个断言 ⇒ assert(i < _size)

这里, 我们开了10个空间 ⇒ _capacity = 10;

但 _size(数据个数) = 0;

⇒ 由于断言, 我们是不能插入数据的

如果要用 []来进行插入数据, 那么我们要用如下的方式👇👇👇

cpp 复制代码
vector<int> vec;
vec.resize(10);

for (int i = 0; i < 10; i++)
{
	vec[i] = i;
}

那我们非要用 reverse 来进行插入数据, 那么我们不应该用 [], 而是用 push_back

  1. push_back 和 _size没有关系, 不够了也只是扩容而已
  2. push_back过后, _size是会进行++的
cpp 复制代码
vector<int> vec;
vec.reserve(10);

for (int i = 0; i < 10; i++)
{
	vec.push_back(i);
}

由此, 我们可以得出:

  1. operator[] 是跟 _size 密切相关的
  2. push_back 的使用就比较宽松
  3. 并不是开好了空间, 就一定能进行插入数据的

人需在事上磨,方可立得住,方能静亦定,动亦定. --- ---- 王阳明
译:有个学生问王阳明,安静的时候我感觉很不错,思想清晰,可一遇到事情就乱了阵脚,为什么?
王阳明说:"这是你只知道静养,却没有下克己的功夫.这样一来,碰到事情就乱了阵脚. 人应该在具体的事情上磨炼自己,才能站得稳,才能静亦定,动亦定.

相关推荐
myprogramc5 分钟前
十大排序算法
数据结构·算法·排序算法
记得早睡~8 分钟前
leetcode150-逆波兰表达式求值
javascript·算法·leetcode
qy发大财11 分钟前
跳跃游戏(力扣55)
算法·leetcode
BingLin-Liu14 分钟前
蓝桥杯备考:搜索算法之排列问题
算法·职场和发展·蓝桥杯
mit6.82416 分钟前
[实现Rpc] 通信-Muduo库的实现 | && 完美转发 | reserve | unique_lock
c++·网络协议·rpc
计算机小白一个17 分钟前
蓝桥杯 Java B 组之岛屿数量、二叉树路径和(区分DFS与回溯)
java·数据结构·算法·蓝桥杯
孤雪心殇18 分钟前
简单易懂,解析Go语言中的Map
开发语言·数据结构·后端·golang·go
庸俗今天不摸鱼30 分钟前
Canvas进阶-4、边界检测(流光,鼠标拖尾)
开发语言·前端·javascript·计算机外设
菠菠萝宝31 分钟前
【Java八股文】10-数据结构与算法面试篇
java·开发语言·面试·红黑树·跳表·排序·lru
奔跑吧邓邓子33 分钟前
【Python爬虫(36)】深挖多进程爬虫性能优化:从通信到负载均衡
开发语言·爬虫·python·性能优化·负载均衡·多进程