Vector容器是C++ STL中的一个动态数组容器,可以在运行时动态地增加或减少其大小,存储相同数据类型的元素,提供了快速的随机访问和在末尾插入或删除元素的功能。
该容器可以方便、灵活地代替数组,容器可以实现动态对数组扩容删除等各种复杂操作,其时间复杂度O(l)常数阶
,其他元素的插入和删除为O(n)线性阶
,其中n为容器的元素个数,vector具有自动的内存管理机制,对于元素的插入和删除可动态调整所占用的内存空间。
2.1 数组向量基础应用
如下C++代码,展示了如何使用STL的vector
容器对数组进行元素添加、弹出、大小重置和空间调整等操作,并使用自定义函数MyPrint()
输出结果。
在代码中,首先使用初始化列表给vector<int>
容器var
赋初值{ 1, 2, 3 }
。
使用push_back()
函数向容器中添加元素4,并使用MyPrint()
函数输出结果。
使用pop_back()
函数弹出容器中的一个元素,并再次使用MyPrint()
函数输出结果。
使用resize()
函数重新设置容器的最大存储空间为10,并使用reserve()
函数调整容器的空间大小为30,并再次使用MyPrint()
函数输出结果。
在输出容器中的元素值时,可以使用for循环遍历整个vector
容器,也可以使用for_each()
算法遍历整个vector
容器。在自定义函数MyPrint()
中,使用容器提供的函数empty()、size()、capacity()
和max_size()
来获取容器的一些基本属性信息。
#include <iostream>
#include <algorithm>
#include <vector>
using namespace std;
void MyPrint(vector<int>& var)
{
cout << "empty = " << var.empty() << " --> size = " << var.size() << endl;
cout << "capacity = " << var.capacity() << " --> max_size = " << var.max_size() << endl;
for_each(var.begin(), var.end(), [](int val){ cout << val << endl; });
cout << "---------------------------------------------------------" << endl;
}
int main(int argc, char* argv[])
{
vector<int> var{ 1, 2, 3 };
var.push_back(4); // 放入元素
MyPrint(var);
var.pop_back(); // 弹出一个元素
MyPrint(var);
var.resize(10); // 重新设置最大存储
var.reserve(30); // 调整数据空间大小
MyPrint(var);
system("pause");
return 0;
}
2.2 数组向量正/反向遍历
如下C++代码,展示了三种不同的遍历方法,分别是使用数组下标、使用正向迭代器和反向迭代器遍历,用于演示vector容器遍历的方法。
定义int_array
容器,并使用const_iterator
类型的迭代器item
遍历输出容器中的每个元素。
定义rint_array
容器,使用reverse_iterator
类型的迭代器start
和end
进行反向遍历,遍历输出容器中的每个元素。
在使用迭代器遍历容器时,需要使用begin()
和end()
函数指定迭代器的起始位置和结束位置,反向遍历使用的是rbegin()
和rend()
函数。
#include <iostream>
#include <string>
#include <vector>
using namespace std;
int main(int argc, char* argv[])
{
// 第一种遍历数组的方式,使用数组的下标实现遍历
vector<string> str_array{ "admin", "guest", "lyshark" };
cout << "str_array sizeof:" << str_array.capacity() << endl;
for (int x = 0; x < str_array.size(); x++)
{
cout << "str_array --> " << str_array[x] << endl;
}
cout << endl;
// 第二种遍历数组的方式,使用迭代器实现的正向遍历
vector<int> int_array{ 1, 2, 3, 4, 5 };
vector<int>::const_iterator item;
int each = 0;
for (item = int_array.begin(), each = 0; item != int_array.end(); ++item, ++each)
{
cout << "int_array[" << each << "] --> " << (*item) << endl;
}
cout << endl;
// 第三种遍历数组的方式,使用迭代器实现的反向遍历
vector<int> rint_array{ 1, 2, 3, 4, 5, 6, 7, 8, 9 };
vector<int>::reverse_iterator start, end; // 定义向量迭代器
end = int_array.rend();
for (start = int_array.rbegin(); start != end; start++)
{
cout << "int_array --> " << *start << endl;
}
system("pause");
return 0;
}
2.3 数组向量正/反向排序
如下C++代码,展示了如何使用STL的sort()函数对vector容器进行正向排序和反向排序,并通过迭代器遍历输出结果。
在代码中,首先使用new
运算符动态申请了一个名为int_array
的vector<int>
类型的动态数组,并使用for循环向数组插入10
个随机数。
使用std::sort()
函数对int_array
动态数组进行正向排序,排序时使用了int_array->begin()
和int_array->end()
表示排序的起始位置和结束位置。
通过const_iterator
类型的item
迭代器遍历整个int_array
数组,并使用cout
输出每个元素的值。
使用std::sort()
函数对int_array
动态数组进行反向排序,排序时使用了MyCompare()
回调函数来实现反向排序。
在使用迭代器遍历整个vector
容器时,需要使用begin()
和end()
函数来指定迭代器的起始位置和结束位置。
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
// 实现的一个排序回调函数,反向排序需要使用该回调
bool MyCompare(int value1, int value2){ return value1 > value2; }
int main(int argc, char* argv[])
{
vector<int> *int_array = new vector<int>;
// 生成10个随机数用于测试
for (int x = 0; x < 10; x++)
int_array->push_back(rand() % 100);
// 遍历的方式实现 正向排序
std::sort(int_array->begin(), int_array->end());
vector<int>::const_iterator item = int_array->cbegin();
while (item != int_array->cend())
{
cout << (*item) << " ";
item++;
}
cout << endl;
// 遍历的方式实现 反向排序
std::sort(int_array->begin(), int_array->end(), MyCompare);
vector<int>::const_iterator item_1 = int_array->cbegin();
while (item_1 != int_array->cend())
{
cout << (*item_1) << " ";
item_1++;
}
system("pause");
return 0;
}
2.4 向数组向量中插入元素
如下C++代码,展示了如何使用vector容器对字符串数组进行插入和删除操作,并使用循环遍历输出结果。
在代码中,首先定义了一个vector
容器str_array
,该容器存放的是字符串类型的元素,使用了初始化列表给其赋予了初始值:admin
、guest
和lyshark
。
使用push_back()
函数分别将"django"
和"python"
元素加入到容器的末尾,使用pop_back()
函数弹出容器的末尾元素。
使用insert()
函数在容器的索引2位置及末尾位置分别插入"ruby"
和"C++"
元素。
使用for循环遍历整个vector
容器str_array
,并使用cout
输出每个元素的值。
在输出容器中的元素值时,可以使用下标运算符或迭代器进行遍历。
#include <iostream>
#include <string>
#include <vector>
using namespace std;
int main(int argc, char* argv[])
{
// 定义数组容器,并赋予初始值
vector<string> str_array{ "admin", "guest", "lyshark" };
str_array.push_back("django"); // 插入元素
str_array.push_back("python"); // 插入元素
str_array.pop_back() // 弹出元素
// cout << str_array[3] << endl; // 通过元素下标遍历数据
str_array.insert(str_array.begin() + 2, "ruby"); // 在数组索引2的位置插入元素
str_array.insert(str_array.end(), "C++"); // 在数组最后插入元素
for (int x = 0; x < str_array.size(); x++)
cout << "str_array[" << x << "] --->" << str_array[x] << endl;
system("pause");
return 0;
}
2.5 向数组向量中插入结构指针
如下C++代码,展示了如何定义结构体、创建结构体数组,并在其中加入数据后使用迭代器输出数据。
在代码中,定义了一个名为Person
的结构体,该结构体包含两个成员变量ID
和szName
,并使用typedef
给Person
对象定义了一个Ptr
类型的别名。
使用for循环遍历ary数组,通过迭代器输出每个vector
容器中的第一个元素的ID
和szName
成员变量的值。
在输出结构体数组的成员变量值时,需要使用(*item).ID
和(*item).szName
表示从结构体中取出相应的成员变量值。另外,因为ary是一个结构体数组,所以在遍历ary数组时,需要使用数组下标运算符及迭代器实现。
#include <iostream>
#include <vector>
using namespace std;
typedef struct
{
int ID;
char szName[20];
}Person, *Ptr;
int main(int argc, char* argv[])
{
vector<Person> ary[10];
Person p1 = { 1, "admin" };
Person p2 = { 2, "lyshark" };
Person p3 = { 3, "guest" };
ary[0].push_back(p1);
ary[1].push_back(p2);
ary[2].push_back(p3);
for (int x = 0; x < 3; x++)
{
vector<Person>::iterator item = ary[x].begin();
cout << "ID: " << (*item).ID <<" ---> Name: " << (*item).szName << endl;
}
system("pause");
return 0;
}
2.6 向数组向量中插入类指针
如下C++代码,展示了如何以指针类型存储对象,并使用迭代器进行遍历。
代码中定义了MyAnimal
类,并分别实例化了pDog、pMonkey
和pSnake
三个成员,通过使用push_back()
函数将这三个对象指针加入到var中,最后通过使用遍历的方法输出该迭代器中的所有元素。
在进行遍历时,需要使用迭代器类型的元素,记得要保证迭代器的有效性。
#include <iostream>
#include <vector>
using namespace std;
class MyAnimal{
public:
char *name;
int id;
public:
MyAnimal(char* name, int id)
{
this->name = name;
this->id = id;
}
};
int main(int argc, char* argv[])
{
MyAnimal* pDog = new MyAnimal("dog", 1);
MyAnimal* pMonkey = new MyAnimal("monkey", 2);
MyAnimal* pSnake = new MyAnimal("psnake", 3);
vector<MyAnimal *> var; // 定义模板
var.push_back(pDog); // 将指针放入列表
var.push_back(pMonkey);
var.push_back(pSnake);
// 指针列表的遍历器
vector<MyAnimal*>::iterator start, end;
end = var.end();
for (start = var.begin(); start != end; start++)
{
cout <<"ID: "<<(*start)->id << " ---> " << "Name: " << (*start)->name << endl;
}
system("pause");
return 0;
}
2.7 在数组容器中嵌套容器
如下C++代码,展示了如何定义和遍历内嵌在vector容器中的子容器。
在代码中,首先定义vector<vector<int>>
的变量var,它是一个外层vector
容器,其中包含两个内层的vector容器v1和v2。
接着,使用for循环分别向内层vector
容器v1和v2中插入了5个整数元素。然后,将内层vector
容器v1和v2分别插入到外层vector
容器var中。此时,var中包含了两个内层vector容器。
代码使用双重循环遍历所有容器中的数据,首先遍历var中的外层容器,然后分别遍历内层容器v1和v2,输出其中的元素值。
#include <iostream>
#include <vector>
using namespace std;
int main(int argc, char* argv[])
{
// 容器中内嵌容器
vector< vector<int> > var;
vector<int> v1;
vector<int> v2;
for (int x = 0; x < 5; x++)
{ // 放入小容器中的数据
v1.push_back(x);
v2.push_back(x + 10);
}
// 将小容器放入大容器中
var.push_back(v1);
var.push_back(v2);
// 遍历所有容器中的数据, 由于是嵌套容器,所以我们要先来遍历第一层,在第一层中遍历第二层.
for (vector<vector<int>>::iterator item = var.begin(); item != var.end(); item++)
{
for (vector<int>::iterator vitem = (*item).begin(); vitem != (*item).end(); vitem++)
{
cout << (*vitem) << " ";
}
cout << endl;
}
system("pause");
return 0;
}
2.8 函数参数定义为容器类型
如下C++代码,展示了如何创建向量容器(vector)并实现容器间的构造、赋值、互换等操作。
代码使用两种方式构造了包含整数元素的向量容器v1和v2。其中,v1使用数组arry
和sizeof(arry)/sizeof(int)
的方式进行初始化。v2则继承自v1,使用了迭代器的方式初始化。
代码在v3中使用assign()
函数生成10个元素为20的向量容器,并使用MyPrintVector()
打印出v3中的元素。
代码使用v3中的元素对v4进行赋值,并使用MyPrintVector()
打印出v4中的元素。
代码使用swap()
函数交换v2和v4中的元素,并使用MyPrintVector()
打印出v4中的元素,此时v4已经包含了原先的v2的元素。
#include <iostream>
#include <vector>
using namespace std;
void MyPrintVector(vector<int> &var)
{
for (vector<int>::iterator item = var.begin(); item != var.end(); item++)
{
cout << (*item) << " ";
}
cout << endl;
}
int main(int argc, char* argv[])
{
vector <int> var;
int arry[] = { 1, 2, 3, 4, 5 };
// 两种不同的容器构造方式
vector<int> v1 (arry, arry + sizeof(arry) / sizeof(int));
vector<int> v2(v1.begin(), v1.end());
MyPrintVector(v2); // 打印v2容器中的内容
vector<int> v3(10, 20); // 生成容器,里面包含10个20
MyPrintVector(v3);
vector<int> v4; // 赋值的使用,里面包含10个20
v4.assign(v3.begin(), v3.end());
MyPrintVector(v4);
v4.swap(v2); // v2与v4容器内容互换
MyPrintVector(v4);
system("pause");
return 0;
}
2.9 数组向量元素的删除
如下C++代码,展示了如何删除vector容器中指定的元素,并通过遍历输出剩余的元素。
在代码中,定义了vector<int>
类型的变量int_array
,并使用花括号列表初始化的方式插入了10个整数元素。
使用find()
函数查找元素7在vector中的位置,并使用erase()
函数将此位置处的元素从vector中删除。如果元素7不存在于vector中,则不进行任何操作。
需要注意的是,在遍历vector时,可以使用迭代器类型的元素,也可以使用下标访问以控制循环次数。但需要确保迭代器的有效性,因为erase()
函数会使迭代器失效,从而导致遍历错误。
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
int main(int argc, char* argv[])
{
vector<int> int_array {1,2,3,4,5,6,7,8,9,10};
// find 找到元素7并删除
vector<int>::iterator item = find(int_array.begin(), int_array.end(), 7);
if (item != int_array.cend())
int_array.erase(item); // 删除指定元素
// 删除后对数组进行遍历
vector<int>::iterator start, end;
end = int_array.end();
for (start = int_array.begin(); start != end; start++)
{
cout << (*start) << endl;
}
system("pause");
return 0;
}