数组的缺陷
- 数组在定义时大小固定,不能改变
- 如果要定义在main内部,数组大小不能超过一百万(6个0),超过需要定义为全局变量
- 定义在main内部,数组创建在内存的栈中,作为局部变量,但栈的空间比较小
- 定义为全局变量,数组创建在内存的数据段中,空间比较大,但无法自动回收空间
向量vector(可以看作动态数组)
vector类型在内存中顺序存储,采用线性表结构,引入的头文件为:
#include <vector>
using namespace std;
创建vector及添加元素
逐一添加(尾部扩容)(效率最高)
vector<int> vec1;//初始长度为0
//尾部扩容
vec1.push_back(1);//vec1[0]=1
vec1.push_back(3);//vec1[1]=3
printf("%d",vec1[1]);
定义时添加多个
vector<int> vec2 = {0,1,2};//一开始就有3个元素
定义时声明极大的空间,初值默认都为0
vector<int> vec3(10000);//vec3[0]-[9999]都为0
尾部弹出
vector<int> vec2 = {0,1,2};//一开始就有3个元素
vec2.pop_back();//弹出最后一个元素,不需要传入参数
访问(使用[ ])
注意,vec.size()可以获取长度
for (unsigned i = 0; i < vec1.size(); ++i) {
printf("vec[%d] = %d",i,vec1[i]);
}
迭代器(指针)遍历法
- vec.begin():起始迭代器
- vec.end():尾后迭代器
for (vector<int>::iterator i = vec1.begin(); i != vec1.end() ; ++i) {
printf("vec[] = %d\n",*i);
}
随机位置的插入和删除
vector<int>::iterator i = vec1.begin()+1;//在vec1[1]处插入
vec1.insert(i,4);
vec1.erase(vec1.begin());//vec1[0]删除,后面的往前移
例题
【提交地址】
代码
#include <cstdio>
#include <string>
#include <map>
#include <algorithm>
#include <vector>
using namespace std;
int sum(int i) {
int sum = 0;
for (int j = 1; j < i; ++j) {
if (i%j==0){
sum+=j;
}
}
return sum;
}
int main() {
vector<int> vec_E;//完数
vector<int> vec_G;//盈数
for (int i = 2; i <= 60; ++i) {
if (i == sum(i)){
vec_E.push_back(i);
} else if (i < sum(i)){
vec_G.push_back(i);
}
}
printf("E:");
for (int i = 0; i < vec_E.size(); ++i) {
printf(" %d",vec_E[i]);
}
printf("\nG:");
for (int i = 0; i < vec_G.size(); ++i) {
printf(" %d",vec_G[i]);
}
return 0;
}
vector的底层逻辑
存储方式
vector类型,即使定义在main函数内部,也能定义超过1000万的数组大小,原因在于,vector是一个类,其中有size(容量)、capacity(内存大小)、ptr(内存首地址),其中ptr指向内存的堆区,vector扩容时实际改变的是占用堆空间的大小
扩容机制
当size逐渐增大,达到capacity的大小,将执行以下步骤
- 申请内存中2*capacity的大小
- 将已经写在vector中的数据copy到新的空间中
- 释放原有的空间
从理论上来说,每次插入一个元素,复杂度是 O ( 1 ) O(1) O(1)