C++ 标准库(Standard Template Library, STL)是 C++ 的一个重要组成部分,它提供了一组通用的模板类和函数,用于处理数据集合。<vector>
是 STL 中的一个容器类,用于存储动态大小的数组。
<vector>
是一个序列容器,它允许用户在容器的末尾快速地添加或删除元素。与数组相比,<vector>
提供了更多的功能,如自动调整大小、随机访问等。
在 C++ 中,使用 <vector>
需要包含头文件 <<vector>>
。
基本的语法
using namespace std;
vector<int> myVector;//声明一个 vector
myVector.push_back(10);//向容器内添加元素
int firstElement = myVector[0];//访问元素
size_t size = myVector.size();//获取元素数量
声明与初始化
#include <iostream>
#include <vector>
int main() {
std::vector<int> vec1; // 空的vector
std::vector<int> vec2(5); // 长度为5的vector,元素默认初始化
std::vector<int> vec3(5, 10); // 长度为5的vector,元素值为10
std::vector<int> vec4 = {1, 2, 3, 4}; // 使用初始化列表初始化
return 0;
}
成员函数
一维容器的遍历
底层逻辑
STL众多容器中,vector 是最常用的容器之一,其底层所采用的数据结构非常简单,就只是一段连续的线性内存空间。
通过分析 vector 容器的源代码不难发现,它就是使用 3 个迭代器(可以理解成指针)来表示的:
//_Alloc 表示内存分配器,此参数几乎不需要我们关心
template <class _Ty, class _Alloc = allocator<_Ty>>
class vector{
...
protected:
pointer _Myfirst;
pointer _Mylast;
pointer _Myend;
};
其中,_Myfirst 指向的是 vector 容器对象的起始字节位置;_Mylast 指向当前最后一个元素的末尾字节;_myend 指向整个 vector 容器所占用内存空间的末尾字节。
如图 1 所示,通过这 3 个迭代器,就可以表示出一个已容纳 2 个元素,容量为 5 的 vector 容器。
在此基础上,将 3 个迭代器两两结合,还可以表达不同的含义,例如:
- _Myfirst 和 _Mylast 可以用来表示 vector 容器中目前已被使用的内存空间;
- _Mylast 和 _Myend 可以用来表示 vector 容器目前空闲的内存空间;
- _Myfirst 和 _Myend 可以用表示 vector 容器的容量。
vector的底层会用三个指针,利用三个指针相减来实现动态存储。
二维向量
二维容器的初始化
vector<vector<int>> a(r, vector<int>(c));
int row = a.size(); //获取行数
int column = a[0].size(); //获取列数
vector< vector<int> > a(r, vector<int>(c, 0)); //初始化行为r,列为c,元素为0
算法实战,递归,深度优先搜索
输入输出样例
4 3
5 7 12 19
1
#include <iostream>
#include <vector> //使用向量需要的头文件,当然你也可以使用万能头文件<bits/stdc++.h>
using namespace std;
vector<int> nums; // 存储输入的整数数组
vector<int> combination; // 存储当前组合
int n, k; // n个数中选k个
int count = 0; // 记录满足条件的组合数
// 判断一个数是否为素数
bool isPrime(int num) {
if (num < 2) return false;
for (int i = 2; i * i <= num; i++) {
if (num % i == 0) return false;
}
return true;
}
// 深度优先搜索函数
void dfs(int start, int selected) {
if (selected == k) {
int sum = 0;
for (int num : combination) {
sum += num;
}
if (isPrime(sum)) {
count++;
}
return;
}
for (int i = start; i < n; i++) {
combination.push_back(nums[i]);//容器尾部添加元素
dfs(i + 1, selected + 1);
combination.pop_back();//直接pop栈顶或者说尾部元素,无需在括号里面加value
}
}
int main() {
cin >> n >> k;
nums.resize(n);//重新构建容器大小当然也可以初始化时构建大小
for (int i = 0; i < n; i++) {
cin >> nums[i];
}
dfs(0, 0);
cout << count << endl;
return 0;
}
时间复杂度分析:时间开销主要来自递归深度,而的递归深度又和数据规模有关,相当于排列组合数,n个数选k个,最坏情况下n与k相同数量规模.