文章目录
1.vector与数组
1.1 增删改查
数组
和向量
都可以用来存储元素列表,向量可以用来替换数组,且比数组更灵活(类vector包含很多成员函数)。但是,如果列表大小固定,则使用数组会更加高效。
关于数组和向量的不同和相似之处如下表所示:
操作 | 数组 | 向量 |
---|---|---|
创建一个数组/向量 | string a[10] | vector<string> v |
访问一个元素 | a[index] | v[index] |
更新一个元素 | a[index] = “China” | v[index ] = " China" |
返回大小 | sizeof(a)/sizeof(a[0]) | v.size() |
追加新的元素 | v.pusk_back(“Chian”) | |
删除(最后的)元素 | v.pop_back() | |
删除所有的元素 | v.clear() |
1.2 复杂度
操作 | 时间复杂度 |
---|---|
push_back() | O(1) |
pop_back() | O(1) |
insert() | O(n) |
erase() | O)(n) |
注释
- vector是动态数组,在堆中分配内存
- vector与数组一样,都是分配的一段
连续的内存空间
,并且起始地址不变,因此能够很好支持随机存取
,复杂度为 O ( 1 ) O(1) O(1) 。但是在头部或者中间进行插入和删除的时候会涉及元素的移动
,即内存块的拷贝
,所以在中间插入或者删除元素的复杂度为 O ( n ) O(n) O(n) - 对最后元素操作最快(在后面添加删除元素最快),此时一般不需要移动内存。
2.vector的用法
vector是一个模板类
所以使用时要用vector<int> a 这样的方式来声明一个vector,即
template<typename T>
vector<T> vectorname;
初始化vector的方法:
2.1 基本用法
操作 | 含义 |
---|---|
vector<T> name | 声明一个名为name的向量 |
c.back() | 传回最后一个数据,不检查这个数据是否存在 |
clear() | 删除所有元素 |
erase() | 删除一个或者多个元素 |
empty() | 测试是否为空 |
c.front() | 传回第一个数据 |
push_back() | 在尾部添加元素 |
pop_back() | 在尾部删除元素 |
resize() | 改变大小 |
size() | 返回v中元素个数 |
- vector之间可以直接赋值或者作为函数的返回值
- push_back()和pop_back()无需改变数组长度,自动会增加和减小数组长度
- 增加长度后增加的元素值为0
示例代码:
#include<iostream>
#include<vector> //vector类需要添加的头文件
using namespace std;
int main() {
//声明并初始化一个向量a = [0,1,2,3,4]
vector<int> a;
for (int i = 0; i < 5; i++) a.push_back(i); //在末尾追加数
cout << "print1 a的值:" << endl;
for (int i = 0; i < a.size(); i++) {
cout << a[i] << " ";
}
cout << endl;
//向量间直接赋值
vector<int> b;
b = a;
cout << "print2 b=a: 直接赋值" << endl;
for (int i = 0; i < b.size(); i++) {
cout << b[i] << " ";
}
cout << endl;
//改变大小
cout << "a.size() = " << a.size() << endl;
a.resize(7);
cout << "a.size() = after resize(7) :" << a.size() << endl;
cout << "print3 after resize(7):" << endl;
for (int i = 0; i < a.size(); i++) {
cout << a[i] << " ";
}
cout << endl;
//在尾部删除元素
a.pop_back();
cout << "a.size() = after pop_back() :" << a.size() << endl;
cout << "print4 after pop_back():" << endl;
for (int i = 0; i < a.size(); i++) {
cout << a[i] << " ";
}
cout << endl;
//测试是否为空
cout << "a.empty()?:" << a.empty() << endl;
//删除某一元素
a.erase(a.begin()+2); //删除a[2]
cout << "print5 after erase a[2]:" << endl;
for (int i = 0; i < a.size(); i++) {
cout << a[i] << " ";
}
cout << endl;
//清空所有元素
a.clear();
cout << "a.size() = after a.clear() :" << a.size() << endl;
cout << "a.empty()? after a.clear(): " << a.empty() << endl;
cout << "print6 after a.clear():" << endl;
for (int i = 0; i < a.size(); i++) {
cout << a[i] << " ";
}
cout << endl;
return 0;
}
输出结果
print1 a的值:
0 1 2 3 4
print2 b=a: 直接赋值
0 1 2 3 4
a.size() = 5
a.size() = after resize(7) :7
print3 after resize(7):
0 1 2 3 4 0 0
a.size() = after pop_back() :6
print4 after pop_back():
0 1 2 3 4 0
a.empty()?:0
print5 after erase a[2]:
0 1 3 4 0
a.size() = after a.clear() :0
a.empty()? after a.clear(): 1
print6 after a.clear():
2.2 STL中vector的方法:
2.2.1 非变动操作
操作 | 含义 |
---|---|
c.capacity() | 返回重新分配空间前可容纳的最大元素数量 |
c.empty() | 判断容器是否为空 |
c.max_size() | 返回容器最大容纳数据的数量(固定值) |
c.resize(num) | 重新指定队列的长度 |
c.reserve(n) | 保留容量为n |
c.size() | 返回容器中实际数据的个数 |
2.2.2 赋值操作
操作 | 含义 |
---|---|
c1 = c2 | 将c2的全部元素赋值给c1 |
c.assign(n,elem) | 将n个elem的拷贝赋值给c |
c.assign(beg,end) | 将[beg; end)区间中的数据赋值给c |
c1.swap(c2) | 将c1和c2元素互换 |
swap(c1,c2) | 同上,全局函数 |
2.2.3 元素存取
操作 | 含义 |
---|---|
c. at(idx) | 传回索引idx所指的数据,如果idx越界,抛出out_of_range |
c.front() | 传回第一个数据 |
c.back() | 传回最后一个数据,不检查这个数据是否存在 |
2.2.4 迭代器相关函数
操作 | 含义 |
---|---|
c.begin() | 返回一个迭代器,指向第一个元素(即是指向第一个数据的一个指针) |
c.end() | 返回一个迭代器(指针),指向最后一个元素的下一个位置(实际不存在) |
c.rbegin() | 返回一个逆向迭代器,指向逆向遍历的第一个元素 |
c.rend() | 返回一个逆向迭代器,指向最后一个数据的下一个位置 |
迭代器持续有效,除非发生下面两种情况:
- 删除或插入元素
- 容量变化而引起的内存重新分配
2.2.5 插入(insert)元素
操作 | 含义 |
---|---|
c.insert(pos,elem) | 在pos位置插入一个elem拷贝,传回新数据位置 |
c.insert(pos,n,elem) | 在pos位置插入n个elem数据,无返回值 |
c.insert(pos,beg,end) | 在pos位置插入在[beg,end)区间的数据。无返回值 |
c.push_back(elem) | 在尾部加入一个元素elem的副本 |
2.2.6 移除(remove)元素
操作 | 含义 |
---|---|
c.pop_back() | 删除最后一个数据 |
c.erase(pos) | 删除pos位置的数据,传回下一个数据的位置 |
c.erase(beg,end) | 删除[beg,end)区间的数据,传回下一个数据的位置 |
c.clear() | 移除容器中所有数据 |
c.resize(num) | 将元素数量改为num(增加的元素默认初始化,多余的元素被删除) |
c.resize(num.e) | 将元素数量改为num(增加的元素是e的副本) |
注意:
vector的v.erase()
v.erase(v.begin()+2);//删除v[2]元素
v.erase(v.begin()+2,v.begin()+5);//删除v[2] v[3] v[4]
v.clear();//清空
示例代码:
#include<iostream>
#include<vector> //vector类需要添加的头文件
using namespace std;
int main() {
//声明并初始化一个数组a = [0,1,2,3,4,4,4]
int a[] = { 0,1,2,3,4 ,4,4};
//将数组a的值赋值给向量b;
vector<int> b;
int alen = sizeof(a) / sizeof(a[0]); //数组a的长度
cout << "print 数组a的长度:" << alen << endl;
b.assign(a, a + alen); //注意c.assign(beg,end)中beg和end是区间地址边界,不包含end
cout << "print1 赋值后b的值:" << endl;
for (int i = 0; i < b.size(); i++) {
cout << b[i] << " ";
}
cout << endl;
cout << "print2 b的最后一个值:" << b.back() << endl; //返回的是一个数值
cout << "print3 b的第一个值:" << b.front() << endl; //返回的是一个数值
printf("print4 b的迭代器第一个元素的地址: %p\n", b.begin()); //返回的是地址
cout << "print5 b的第一个元素的地址&b[0]:" << &b[0] << endl; //发现和上面并不相等
cout << "print6 b的迭代器的第一个元素的地址中所存储的值:" << *b.begin() << endl;
return 0;
}
输出结果:
print 数组a的长度:7
print1 赋值后b的值:
0 1 2 3 4 4 4
print2 b的最后一个值:4
print3 b的第一个值:0
print4 b的迭代器第一个元素的地址: 00E02FF0
print5 b的第一个元素的地址&b[0]:00E02098
print6 b的迭代器的第一个元素的地址中所存储的值:0
请按任意键继续. . .
2.3 vector声明多维向量
多维数组可以用嵌套的向量来实现,如二维数组可以用向量的向量来实现。
例如下面代码实现对二位数组求和:
#include<iostream>
#include<vector> //vector类需要添加的头文件
using namespace std;
int sum(vector<vector<int>>& matrix) {
int total = 0;
for (int i = 0; i < matrix.size(); i++) {
for (int j = 0; j < matrix[i].size(); j++) total += matrix[i][j];
}
return total;
}
int main() {
vector<vector<int>> matrix(4); //4行
for (int i = 0; i < 4; i++) matrix[i] = vector<int>(3); //每行3列
for (int i = 0; i < 4; i++) {
for (int j = 0; j < 3; j++) matrix[i][j] = 3 * i + j + 1;
}
cout << "print1 矩阵matrix: " << endl;
for (int i = 0; i < 4; i++) {
for (int j = 0; j < 3; j++) cout << matrix[i][j]<<" ";
cout << endl;
}
cout << "print2 矩阵matrix第一维度: " << matrix.size() << endl;
cout << "print3 矩阵matrix第二维维度: " << matrix[0].size() << endl;
cout << "print4 矩阵matrix所有元素的和 " << sum(matrix) << endl;
return 0;
}
输出结果:
print1 矩阵matrix:
1 2 3
4 5 6
7 8 9
10 11 12
print2 矩阵matrix第一维度: 4
print3 矩阵matrix第二维维度: 3
print4 矩阵matrix所有元素的和 78
请按任意键继续. . .
参考资料
1.柳婼 の blog
https://www.liuchuo.net/archives/tag/c/page/6
2.Introduction to Programming with C++. Y.Daniel Liang著.