算法学习第二弹——STL库学习 之 vector
早上好啊,大佬们,最近都学了什么呀。在上一篇里,我们学了一些C++里面的基础操作和string类型,然后这一篇就开始我们STL库的学习,都很重要喔。
链接:https://pan.quark.cn/s/543c6416746e
提取码:s44L
STL库的内容:
-
容器(Containers):
- 提供了多种数据结构,如向量(
vector
)、列表(list
)、双端队列(deque
)、集合(set
)、映射(map
)等,用于存储数据集合。
- 提供了多种数据结构,如向量(
-
算法(Algorithms):
- 提供了一组通用算法,如排序(
sort
)、搜索(find
)、变换(transform
)、复制(copy
)等,这些算法可以在任何容器上操作。
- 提供了一组通用算法,如排序(
-
迭代器(Iterators):
- 提供了一种访问容器中元素的方法,而不需要关心容器的内部实现。迭代器有多种类型,如输入迭代器、输出迭代器、前向迭代器、双向迭代器和随机访问迭代器。
-
配对(Pairs)和元组(Tuples):
pair
用于存储两个相关联的值,而tuple
可以存储多个值,它们都是模板类。
-
函数对象(Functors) 和 Lambda 表达式:
- 函数对象是重载了函数调用操作符的类,而 Lambda 表达式提供了一种简洁的方式来创建匿名函数对象。
OK,下面我们来一个个进行了解:
学习大纲
本篇里面我们先学vector,那么就让我们开始吧
vector
头文件:<vector>,或者直接使用万能头文件。
vector数据结构和 数组 非常类似,也称为单端数组。
区别在于 数组是静态空间,而 vector 可以动态扩展。
对于它的动态扩展,它并不是在原空间之后续接新空间,而是找更大的内存空间,然后将原数据拷贝新空间,释放原空间。就类似于你开了一个数组,但是用着用着发现它不够长,然后你重新开了一个更大的数组,把原来数组里的内容拷贝了一份到这个数组里。
初始化
四种初始化方式
vector<T> v; //采用模板实现类实现,默认构造函数
vector(v.begin(),v.end()); //将v{begin(), end()区间中的元素拷贝给本身。
vector(n, elem); //构造函数将n个elem拷贝给本身
vector(const vector &vec); //拷贝构造函数,
#include <bits/stdc++.h>
using namespace std;
int main()
{
int temp[100]={1,2,3,4,5,6,7,8};
vector<int> v1; //默认构造
for (int i=0; i<10; i++){
v1.push_back(i); //向v1中添加元素的语句
}
vector<int> v2(v1.begin(), v1.end()); //区间构造
vector<int> v3(10, 100); //n个elem方式构造
vector<int> v4(v3); //拷贝构造
cout << "v1: ";
for (auto z:v1) cout << z << " "; //循环遍历vector容器输出结果。
cout << "\nv2: ";
for (auto z:v2) cout << z << " ";
cout << "\nv2: ";
for (auto z:v3) cout << z << " ";
cout << "\nv4: ";
for (auto z:v4) cout << z << " ";
cout << "\n";
return 0;
}
/*
v1: 0 1 2 3 4 5 6 7 8 9
v2: 0 1 2 3 4 5 6 7 8 9
v2: 100 100 100 100 100 100 100 100 100 100
v4: 100 100 100 100 100 100 100 100 100 100
*/
赋值
三种方式:
vector& operator=(const vector &vec); //重载等号操作符
assign(beg, end); //将[beg,end)区间中的数据拷贝赋值给本身。
assign(n,elem); //将n个elem拷贝赋值给本身
#include <bits/stdc++.h>
using namespace std;
int main()
{
int temp[100]={1,2,3,4,5,6,7,8};
vector<int> v1;
cout << "v1: ";
for (int i=0; i<10; i++){
v1.push_back(i);
}
for (auto z:v1) cout << z << " ";
vector<int> v2;
v2 = v1;
cout << "\nv2: ";
for (auto z:v2) cout << z << " ";
vector<int> v3;
v3.assign(v1.begin(), v1.end());
cout << "\nv3: ";
for (auto z:v3) cout << z << " ";
return 0;
}
/*
v1: 0 1 2 3 4 5 6 7 8 9
v2: 0 1 2 3 4 5 6 7 8 9
v3: 0 1 2 3 4 5 6 7 8 9
*/
容量和大小
empty(); //判断容器是否为空
capacity(); //容器的容量
size(); //返同容器中元素的个数
resize(int num);//重新指定容器的长度为num,若容器变长,则以默认值填充新位置
//如果容器变短,则末尾超出容器长度的元素被删除。
resize(int nun, elem);//重新指定容器的长度为num,若容器变长,则以elem值填充新位置
如果容器变短,则未尾超出容器长度的元素被删除
empty
#include <bits/stdc++.h>
using namespace std;
int main()
{
vector<int> v1;
vector<int> v2(5, 10);
if (v1.empty())
{
cout << "v1 is empty" << "\n";
}
else
{
cout << "v1 is not empty" << "\n";
}
if (v2.empty())
{
cout << "v2 is empty" << "\n";
}
else
{
cout << "v2 is not empty" << "\n";
}
return 0;
}
/*
v1 is empty
v2 is not empty
*/
cepacity && size
#include <bits/stdc++.h>
using namespace std;
int main()
{
vector<int> v1;
cout << "v1 容量:" << v1.capacity() << "; v1 大小:" << v1.size() << "\n";
for (int i=0; i<10; i++)
{
v1.push_back(i);
}
cout << "v1 容量:" << v1.capacity() << "; v1 大小:" << v1.size() << "\n";
return 0;
}
/*
v1 容量:0; v1 大小:0
v1 容量:16; v1 大小:10
*/
resize
#include <bits/stdc++.h>
using namespace std;
int main()
{
vector<int> v1;
v1.resize(15, 100);
for (int z:v1) cout << z << " ";
cout << "\n";
v1.resize(5);
for (int z:v1) cout << z << " ";
cout << "\n";
return 0;
}
/*
100 100 100 100 100 100 100 100 100 100 100 100 100 100 100
100 100 100 100 100
*/
插入 和 删除
push back(ele); //尾部插入元素ele
pop _back(); //删除最后一个元素
insert(const iterator pos,ele);//迭代器指向位置pos插入元素ele
insert(const_iterator pos,int count,ele);//迭代器指向位置p0s插入count个元素ele
erase(const iterator pos); //删除迭代器指向的元素
erase(const iterator start,const iterator end); //删除迭代器从start到end之间的元素
clear(); //删除容器中所有元素
push_back() && pop_back()
#include <bits/stdc++.h>
using namespace std;
int main()
{
vector<int> v1;
for (int i=0; i<5; i++){
v1.push_back(i);
for (int z:v1) cout << z << " ";
cout << "\n";
}
for (int i=0; i<3; i++){
v1.pop_back();
for (int z:v1) cout << z << " ";
cout << "\n";
}
return 0;
}
insert && erase
#include <bits/stdc++.h>
using namespace std;
int main()
{
vector<int> v1;
v1.insert(v1.begin(), 100);
for (int z:v1) cout << z << " ";
cout << "\n";
v1.insert(v1.begin(), 5, 777);
for (int z:v1) cout << z << " ";
cout << "\n";
v1.erase(v1.begin());
for (int z:v1) cout << z << " ";
cout << "\n";
v1.erase(v1.begin(), v1.end());
for (int z:v1) cout << z << " ";
cout << "\n"; //全部都被删除了,只输出了一个换行
return 0;
}
/*
100
777 777 777 777 777 100
777 777 777 777 100
*/
clear
#include <bits/stdc++.h>
using namespace std;
int main()
{
vector<int> v1(15, 10);
for (int z:v1) cout << z << " ";
cout << "\n";
v1.clear();
for (int z:v1) cout << z << " ";
cout << "\n"; //清空了v1,只输出一个换行
return 0;
}
/*
10 10 10 10 10 10 10 10 10 10 10 10 10 10 10
*/
数据存取
at(int idx); 返回索引idx所指的数据
[ ] 索引; 返回索引idx所指的数据
front(); 返回容器中第一个数据元素
back(); 返回容器中最后一个数据元素
#include <bits/stdc++.h>
using namespace std;
int main()
{
//[]索取 和 at
vector<int> v1;
for (int i=0; i<10; i++){
v1.push_back(i);
}
cout << v1[2] << "\n";
cout << v1.at(5) << "\n";
//front
cout << "第一个元素:" << v1.front() << "\n";
//back
cout << "最后一个元素:" << v1.back() << "\n";
return 0;
}
/*
2
5
第一个元素:0
最后一个元素:9
*/
互换容器
swap(vec) //将vec与本身的元素互换
#include <bits/stdc++.h>
using namespace std;
int main()
{
vector<int> v1;
vector<int> v2;
for (int i=0; i<10; i++){
v1.push_back(i);
}
for (int i=10; i<20; i++){
v2.push_back(i);
}
v1.swap(v2); //将 v1容器 和 v2容器 内的内容互换
for (int z:v1) cout << z << " ";
cout << "\n";
for (int z:v2) cout << z << " ";
cout << "\n";
return 0;
}
预留空间
reserve(int len); //容器预留len个元素长度,预留位置不初始化,元素不可访问。
#include <bits/stdc++.h>
using namespace std;
int main()
{
vector<int> v1;
int num1 = 0; //记录重新开辟地址的次数
int *p1 = NULL;
for (int i=0; i<100000; i++){
v1.push_back(i);
if (p1 != &v1[0]){
num1++;
p1 = &v1[0];
}
}
cout << num1 << "\n";
vector<int> v2;
v2.reserve(100000);
int num2 = 0; //记录重新开辟地址的次数
int *p2 = NULL;
for (int i=0; i<100000; i++){
v2.push_back(i);
if (p2 != &v2[0]){
num2++;
p2 = &v2[0];
}
}
cout << num2 << "\n";
return 0;
}
/*
18
1
*/
总结
好了,今天这期就到这了,vector的使用还是很多的,要好好学喔!这期的所有代码在开头的链接里了。
Bye,Bye~