C++的vector容器

一、介绍

        C++的vector也被称为单端数组,它的数据结构与数组非常类似

一般用于在尾部进行插入和删除的操作。

二、动态扩充

       与数组不同,vector可以根据需求动态扩展。这里的动态扩展指的是它的空间大小会随着需求而增长,但并不是在原空间的基础上继续增加,而是:

        1. 找到一块的更大的空间

        2. 将原空间的数据拷贝到新空间

        3. 释放原空间

三、vector的使用

                    ※ 在使用vector时,需要添加头文件#include <vector> ※ ※

3.1 vector初始化

        vector提供几种构造函数,用于初始化。vector是一个泛型类,因此在初始化时候,需要确定自身元素的类型,也就是指定具体的泛型,如下所示:

声明解释
vector<T> v;默认构造函数,T为模板类型
vector<T>(v.begin(), v.end());将另一个向量的v[begin(), end()]区间拷贝给自身
vector<T>(int n, T elem)nelem拷贝给自身
vector<T>(const vector &v)拷贝构造函数,将v的内容拷贝给自身
vector<string> v0;//初始化一个元素类型为string的vector对象 v0
vector<string> v1(v0.begin()+1, v0.end());//用v0的 第二个元素 到 最后一个元素 初始化v1
vector<char> v2(5, 'W');//用5个字符W初始化v2
vector<string> v3(v0);//用v0初始化v3

3.2 vector赋值

        vector的赋值通过运算符=assign函数实现:

声明解释
vector& operator=(const vector &v)v的内容拷贝给自身
assign(vector<T>::iterator begin, vector<T>::iterator end);将 [begin, end)区间 拷贝给自身
assign(int n, T elem);nelem拷贝给自身
template<typename T>
void printVector(vector<T> &v) {
	for (T elem : v) {
		cout << elem;
	}
	cout << endl;
}

void demo_vector() {
	vector<char> v0(5, 'A');//v0 = AAAAA
	printVector(v0);
	vector<char> v1 = v0;   //v1 = AAAAA
	printVector(v1);
	v1.assign(v0.begin() + 1, v0.end());//v1 = AAAA
	printVector(v1);
	v1.assign(5, 'B');//v1 = BBBBB
	printVector(v1);
}

3.3 vector容量与大小

        有关获取、设置vector容量及大小的函数,如下所示:

声明解释
capacity()获取当前vector的容量
empty()判断当前vector是否为空
size()获取当前vector中元素的个数
resize(int num)

将vector的长度重新设置为num

1. 如果容量变大,则以默认值填充新位置

2. 如果容量变小,则将末尾超出容器长度的元素删除

resize(int num, T elem)

将vector的长度重新设置为num

1. 如果容量变大,则以elem填充新位置

2. 如果容量变小,则将末尾超出容器长度的元素删除

template<typename T>
void printVector(vector<T> &v) {
	cout << '[';
	for (T elem : v) {
		cout << elem;
	}
	cout << ']' << endl;
}

void demo_vector() {
	vector<int> v0(5, 6);//v0 = 66666
	
	cout << "v0.empty() : " << boolalpha << v0.empty() << endl; //是否为空:false
	cout << "v0.capacity() : " << v0.capacity() << endl;//容量大小:5
	cout << "v0.size() : " << v0.size() << endl;//元素个数:5
	
	v0.resize(7);//容量增大,默认值0填充
	printVector(v0);//6666600
	v0.resize(3);//容量减小
	printVector(v0);//666
	v0.resize(9, 8);//容量增大,用‘B’填充
	printVector(v0);//666888888
}

        程序运行结果为:

3.3 vector插入

        vector的插入,常规的有insert函数,除此以外还有push_back函数。

声明解释
push_back(T ele)尾部插入ele
insert(const_iterator pos,  T ele)迭代器pos位置插入ele
insert(const_iterator pos, int n, T ele)迭代器pos位置插入nele
vector<int> v0(5, 6);//v0 = 66666

v0.push_back(7);//v0 = 666667
v0.insert(v0.begin(), 8);//v0 = 8666667
v0.insert(v0.begin() + 2, 3, 5);//v0 = 8655566667

3.4 vector删除

        vector删除元素的函数有clear()、erase()、pop_back()。

声明解释
push_pop()删除尾部最后一个元素
clear()删除所有元素
erase(const_iterator pos)删除迭代器pos位置指向的那个元素
erase(const_iterator begin, const_iterator end)删除[begin, end) 区间的元素
//用于输出向量元素的函数
template<typename T>
 void printVector(vector<T> &v) {
	 if (v.empty()) {
		 cout << "vector is empty now, no elems." << endl;
		 return;
	}

	cout << '[';
	for (T elem : v) {
		cout << elem;
	}
	cout << ']' << endl;
}

vector<int> v0;
for (int i = 0; i < 10; i++) {
	v0.push_back(i);
}
cout << "v0:";
printVector(v0);//v0 = 0123456789

v0.pop_back();
cout << "After pop_back, v0:";
printVector(v0);//v0=012345678

v0.erase(v0.begin());
cout << "After erase v0.begin(), v0:";
printVector(v0);//v0=12345678

v0.erase(v0.begin() + 1, v0.end() - 2);
cout << "After erase v0.begin()+1 to v0.end()-2, v0:";
printVector(v0);//v0=178

v0.clear();
cout << "After clear, v0 : ";
printVector(v0);//empty

        程序执行结果如下:

 3.5 vector存取

        vector存取元素,通常采用以下三个函数运算符[ ]

声明解释
T at(int index)返回下标index指向的那个元素的值
T front()返回向量中第一个元素的值
T back()返回向量中最后一个元素的值
operator[index]

返回下标index指向的那个元素的值

vector<int> v0;
for (int i = 0; i < 10; i++) {
	v0.push_back(i);
};//v0 = 0123456789

cout << "v0.at(6) : 6 == " << v0.at(6) << endl;//6
cout << "v0.front() : 0 == " << v0.front() << endl;//0
cout << "v0.back() : 9 == " << v0.back() << endl;//9
cout << "v0[7] : 7 == " << v0[7] << endl;//7

3.6 两个vector互换元素

        如果想将v1和v2两个vector中的元素互换,应该采用swap()函数,声明如下:

声明解释
void swap(vector v)将当前向量的元素与v的元素互换
//输出向量所有元素的函数
template<typename T>
 void printVector(vector<T> &v) {
	 if (v.empty()) {
		 cout << "vector is empty now, no elems." << endl;
		 return;
	}

	cout << '[';
	for (T elem : v) {
		cout << elem;
	}
	cout << ']' << endl;
}

vector<int> v0, v1;

for (int i = 0; i < 9; i++) {
	v0.push_back(i);
	v1.push_back(i + 1);
};

cout << "Before swap : " << endl;
cout << "v0 : "; printVector(v0);//v0 = 012345678
cout << ", v1 : "; printVector(v1);//v1 = 123456789


v0.swap(v1);
cout << "After swap : " << endl;
cout << "v0 : "; printVector(v0);//v0 = 123456789
cout << ", v1 : "; printVector(v1);//v1 = 012345678

3.7 vector预留空间

        vector可以reserve函数预留空间,来减少vector在动态扩时候的扩展次数

声明解释
reserve(int len)

为当前vector预存len个元素的长度

(预留位置不初始化,这些元素不可访问

         为了测试reserve函数使用与否的区别,我们就要观察在相同条件下的扩容次数。通过前文我们知道,vector的动态扩容是申请一段更大的空间,因此每次扩容的首地址会变化

        首地址变化的次数 = 扩容次数,由此举例如下:

int demo_vector(bool used_reserve) {
	vector<int> v;
	int extendNum = 0;//用于记录v0的扩容次数
	int* pre_v_address = NULL;//用于记录v0 上次插入元素后,空间的首地址
	
	if (used_reserve) {
		v.reserve(500);
	}

	//将0-999这1000个元素插入v0中
	for (int i = 0; i < 1000; i++) {
		v.push_back(i);

		if (pre_v_address != &v[0]) {
			cout << "Extend when insert " << i << endl;
			//如果v0上次的空间首地址 不等于 当前第一个元素的首地址
			//说明申请了新空间,发生了动态扩容
			pre_v_address = &v[0];//令本次空间首地址 为 当前第一个元素的首地址
			extendNum++;//扩容次数+1
		}
	};

	return extendNum;
}

int main() {
	cout << "With reserve(), extend number is : " << demo_vector(true) << endl;
	cout << "Without reserve(), extend number is : " << demo_vector(false) << endl;

	return 0;
}

        当demo_vector函数的参数分别为truefalse时,分别代表采用不采用reserve函数。程序运行结果如下:

        结果中我们可以观察到,在包含初始申请空间的情况下,适应reserve仅仅扩充3

        没有使用reserve的情况下,扩充次数达到了18次。

  • 3
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值