C 语言里用 int arr[ ] 来定义数组,它的缺点是数组的长度不能随心所欲的改变,而 C++ 中的动态数组 vector(矢量) 可以解决这个问题,甚至可以完全替代;它能够在运行阶段设置数组的长度,在末尾增加新的数据,在中间插入新的值,长度可以任意改变,简直不要太好用(偷笑🤭🤭)
它在头文件 vector 里面,也在命名空间 std 里面;
目录
引入
之前 C 语言里面用 int arr[] 定义数组,它的缺点是数组的长度不能随心所欲的改变,而 C++ 里面有一个能完全替代数组的动态数组 vector (有的书里面把它翻译成矢量, vector 本身就是矢量、向量的意思,但是叫做动态数组或者不定长数组我觉得更好理解,绝大多数中文文档中一般不翻译直接叫它 vector~)
它能够在运行阶段设置数组的长度、在末尾增加新的数据、在中间插入新的值、长度任意被改变
头文件
#include<vector>
using namespace std;
定义
vector 是一个动态数组,创建时可以不为它分配大小,之后用 resize 方法分配大小,也可以一开始就定义大小;
不管在 main 函数里定义还是在全局中定义,它都能够直接将所有的值初始化为 0 (不用显示的写出来,已经默认所有的元素都为 0)
vector<int> v;
//定义一个vector v,定义的时候没有分配⼤小
vector<int> v(20);
//直接定义⻓长度为20的int数组,默认这20个元素值都为0
vector<int> v(10, 8);
// 把10长度的数组中所有的值都初始化为8
【举例】
#include<iostream>
#include<vector>
using namespace std;
int main(){
vector<int> v;
cout << "v.size() = " << v.size() << endl;
vector<int> v1(5);
cout << "v1.size() = " << v1.size() << endl;
for(auto it = v1.begin(); it != v1.end(); it++){
cout << *it << " ";
}
cout << endl;
vector<int> v2(10, 8);
cout << "v2.size() = " << v2.size() << endl;
for(auto it = v2.begin(); it != v2.end(); it++){
cout << *it << " ";
}
return 0;
}
【输出】
输出
使用迭代器器的方式访问 vector
【输出1】
vector<int>::iterator
【举例】
#include<iostream>
#include<vector>
using namespace std;
int main(){
vector<int> v(4);
v[0]=0, v[1]=1, v[2]=2, v[3]=3;
vector<int>::iterator it;
for(it = v.begin(); it != v.end(); it++){
cout << *it << " ";
}
return 0;
}
【输出】
【输出2】
for(auto it = v.begin(); it != v.end(); it++){
cout << *it << " ";
}
这里的 auto 相当于 vector<int>::iterator 的简写;
auto 是C++11⾥里里⾯面的新特性,可以让编译器根据初始值类型直接推断变量的类型。
auto x = 100; // x是int变量 auto y = 1.5; // y是double变量
当然这个在算法里面主要的用处不是这个,而是在STL中使用迭代器的时候, auto 可以代替一大长串的迭代器类型声明:
// 本来vector的迭代器遍历要这样写: for(vector<int>::iterator it = v.begin(); it != v.end(); it++) { cout << *it << " "; } // 现在可以直接替换成这样的写法: for(auto it = v.begin(); it != v.end(); it++) { cout << *it << " "; }
vector 的相关操作
插入
【插入1】
v.push_back(elem)
//在尾部添加一个elem副本
【举例】
#include<iostream>
#include<vector>
using namespace std;
int main(){
vector<int> v;
for(int i = 10; i > 0; i--){
v.push_back(i);
//将数字10~1插入v中
}
for(auto it = v.begin(); it != v.end(); it++){
cout << *it << " ";
//用迭代器输出
}
return 0;
}
【输出】
【插入2】
v.insert(pos, elem)
//在pos位置上插入一个elem副本,并返回新元素位置
v.insert(pos, n, elem)
//在pos位置上插入n个elem副本,无回传值
v.insert(pos, beg, end)
//在pos位置上插入区间[beg; end]内的所有元素的副本的无回传值
【举例】
#include<iostream>
#include<vector>
using namespace std;
vector<int> v, v1, v2(3);
int main(){
v2[0] = 0;
v2[1] = 1;
v2[2] = 2;
for(int i = 1; i <= 10; i++){
v.insert(v.begin(), i);
//在最前面插入新元素。
v1.insert(v1.end(), i);
//在迭代器中第二个元素前插入新元素
v2.insert(v2.begin()+2, i);
//在向量末尾追加新元素。
}
v1.insert(v1.end(), 4, 1);
//在尾部插入4个1
cout << "v: ";
for(auto it = v.begin(); it != v.end(); it++){
cout << *it << " ";
}
cout << "\nv1: ";
for(auto it = v1.begin(); it != v1.end(); it++){
cout << *it << " ";
}
cout << "\nv2: ";
for(auto it = v2.begin(); it != v2.end(); it++){
cout << *it << " ";
}
return 0;
}
【输出】
删除
【删除1】
v.pop_back()
//移除最后一个元素,但不回传
【举例】
#include<iostream>
#include<vector>
using namespace std;
int main(){
vector<int> v;
for(int i = 10; i > 0; i--){
v.push_back(i);
}
cout << "原数组v:";
for(auto it = v.begin(); it != v.end(); it++){
cout << *it << " ";
}
v.pop_back();
cout << "\n 删除后:";
for(auto it = v.begin(); it != v.end(); it++){
cout << *it << " ";
}
v.pop_back();
cout << "\n 删除后:";
for(auto it = v.begin(); it != v.end(); it++){
cout << *it << " ";
}
return 0;
}
【输出】
【删除2】
v.erase(pos)
//移除pos位置上的元素,返回下一元素的位置
v.erase(beg, end)
//移除[beg, end]区间内的所有元素,返回下一元素的位置
【举例】
#include<iostream>
#include<vector>
using namespace std;
int main(){
vector<int> v;
for(int i = 10; i > 0; i--){
v.push_back(i);
}
cout << "原数组v:";
for(auto it = v.begin(); it != v.end(); it++){
cout << *it << " ";
}
v.erase(v.begin());//移除第一个元素,并且元素位置改变
cout << "\n 删除后:";
for(auto it = v.begin(); it != v.end(); it++){
cout << *it << " ";
}
cout << "\nv[0] = " << v[0] << endl;
v.erase(v.begin()+5); //移除第五个元素,并且元素位置改变
cout << "\n 删除后:";
for(auto it = v.begin(); it != v.end(); it++){
cout << *it << " ";
}
cout << "\nv[5] = " << v[5] << endl;
v.erase(v.begin()+5, v.end()-1);
//移除区间[5, v.length()-1]上的元素,并且元素位置改变
cout << "\n 删除后:";
for(auto it = v.begin(); it != v.end(); it++){
cout << *it << " ";
}
return 0;
}
【输出】
修改
v.resize(num)
//将元素数量num(如果size()变大了,
//多出来的新元素都需以default构造函数完成)
v.resize(num, elem)
//将元素数量改为num(如果size()变大了,多出来的新元素都是elem的副本)
【举例】
#include<iostream>
#include<vector>
using namespace std;
int main(){
vector<int> v;
v.resize(8);
cout << v.size();
//先定义一个vector变量v1,然后将长度resize为8,默认这8个元素都是0
return 0;
}
清空
v.clear()
//移除所有元素,将容器清空
vector结构体
vector的元素不仅仅可以是 int, double, string, 还可以是结构体,但是要注意:结构体要定义为全局的,否则会出错。
vector容器中存放结构体变量有两种方式:
1)存放结构体变量本身
2)存放结构体变量的指针
存放结构体变量本身
【举例】
#include<iostream>
#include<algorithm>
#include<vector>
using namespace std;
struct stu{
int num;
float grade;
};
stu student;
vector<stu> v;
bool cmp(const stu& st1,const stu& st2){
return st1.grade > st2.grade;
}
int main(){
int num;
float grade;
for(int i = 0; i < 10; i++){
cin >> num >> grade;
student.num = num;
student.grade = grade;
v.push_back(student);
}
cout << "\n排序前:\n";
//遍历
for(auto it = v.begin(); it != v.end(); it++){
cout << (*it).num << " " << (*it).grade << endl;
}
cout << "\n排序后:\n";
sort(v.begin(), v.end(), cmp);
//排序后再次遍历
for(auto it = v.begin(); it != v.end(); it++){
cout << (*it).num << " " << (*it).grade << endl;
}
return 0;
}
存放结构体变量的指针
【举例】
#include<iostream>
#include<algorithm>
#include<vector>
using namespace std;
struct stu{
int num;
float grade;
};
vector<stu*> v;
bool cmp(const stu* st1,const stu* st2){
return st1->grade > st2->grade;
}
int main(){
int num;
float grade;
for(int i = 0; i < 10; i++){
stu *student = new stu();
cin >> num >> grade;
student->num = num;
student->grade = grade;
v.push_back(student);
}
cout << "\n排序前:\n";
//遍历
for(auto it = v.begin(); it != v.end(); it++){
cout << (*it)->num << " " << (*it)->grade << endl;
}
cout << "\n排序后:\n";
sort(v.begin(), v.end(), cmp);
//排序后再次遍历
for(auto it = v.begin(); it != v.end(); it++){
cout << (*it)->num << " " << (*it)->grade << endl;
}
return 0;
}
vector二维数组
定义并初始化
vector<vector<int> > array(m); //这个m一定不能少
//初始化一个m*n的二维数组
for(int i=0;i<m;i++) {
array[i].resize(n);
}
【举例】
#include<iostream>
#include<vector>
using namespace std;
int main() {
vector< vector<int> > array(4);
for(int i = 0; i < 4; i++) {
array[i].resize(5);
}
//输出二维数组的行和列
cout << "Row: " << array.size()<< "\nColumn: " << array[0].size() << endl;
//输出二维数组
for(int j = 0; j < array.size(); j++) {
for(int k = 0; k < array[0].size(); k++) {
array[j][k] = j+1;
}
}
cout << endl;
for(int j = 0; j < array.size(); j++) {
for(int k = 0; k < array[0].size(); k++) {
cout << array[j][k] << " ";
}
cout << endl;
}
return 0;
}