【C++】vector(上)

个人主页~


vector类

一、vector的介绍和使用

1、vector的介绍

这里是cplusplus官方介绍

vector是表示可变大小数组的序列容器

vector类似于数组,采用连续存储空间来存储元素,可以用下标对vector元素进行访问,但它的大小是可以动态改变的,而且这个改变可以被容器自动处理

因为vector使用动态分配数组来存储它的元素,当新元素插入的时候需要扩容,一般来说进行扩容都是按照倍数扩容的,在VS上以1.5倍扩容,在gcc上以2倍扩容,这样后来的几位数字插入的复杂度就很低了

与其他动态序列容器相比,vector在访问元素的时候更加高效,在末尾添加和删除元素相对高效,对于其它不在末尾的删除和插入操作,效率更低

2、vector的使用

(1)vector的定义

构造函数说明 接口说明
vector() 无参构造
vector(const vector& x) 拷贝构造
vector(size_type n,const value_type& val = value_type()) 构造并初始化n个val
vector(Inputlterator first,Inputlterator last) 使用迭代器进行初始化构造
cpp 复制代码
void test1()
{
	vector<int> v1;
	vector<int> v2(10, 0);
	vector<int> v3(v2);
	vector<int> v4(v2.begin(), v2.end());
}


(2)vector iterator的使用

iterator的使用 接口说明
begin+end 获取第一个数据位置的iterator/const_iterator, 获取最后一个数据的下一个位置的iterator/const_iterator
rbegin+rend 获取最后一个数据位置的reverse_iterator,获取第一个数据前一个位置的reverse_iterator
cpp 复制代码
void test2()
{
	vector<int> v1(10, 0);
	int a = 0;
	for (auto& i : v1)
	{
		i += a;
		a++;
	}
	for (auto it = v1.begin(); it != v1.end(); ++it)
	{
		cout << *it << " ";
	}
	cout << endl;
}

(3)vector 空间增长

容量空间 接口说明
size 获取数据个数
capacity 获取容量大小
empty 判断是否为空
resize 改变size
reserve 改变capacity
cpp 复制代码
void test3()
{
	vector<int> v1(10,0);
	cout << v1.size() << endl;
	cout << v1.capacity() << endl;
	cout << v1.empty() << endl;
	v1.resize(5);
	cout << v1.size() << endl;
	cout << v1.capacity() << endl;
	v1.reserve(15);
	cout << v1.size() << endl;
	cout << v1.capacity() << endl;
}

这里提一下不同模版的resize以及reserve基本是相同的,resize是改变size,reserve是改变capacity,清楚它们之间的一一对应的关系

(4)vector的增删查改

接口 接口说明
push_back 尾插
pop_back 尾删
find 查找
insert 在pos位置之前插入val
erase 删除pos位置的值
swap 交换两个vector的数据空间
operator\[\] 使用下标访问vector

其中vector中没有find,find在标准函数库中有定义,第一个参数是开始位置的迭代器,第二个参数是结束位置的迭代器,第三个参数是一个常量的引用,它可以是任何模版实例化后的常量

cpp 复制代码
void test4()
{
	vector<int> v1(10, 0);
	v1.push_back(1);
	v1.push_back(2);
	v1.pop_back();
	v1.push_back(3);
	auto pos = find(v1.begin(), v1.end(), 3);
	v1.insert(pos, 4);
	v1.erase(v1.end() - 1);
	for (int i = 0; i < v1.size(); i++)
	{
		cout << v1[i] << " ";
	}
	cout << endl;
	vector<int> v2(10, 0);
	v1.swap(v2);
	for (int i = 0; i < v1.size(); i++)
	{
		cout << v1[i] << " ";
	}
	cout << endl;
	for (int i = 0; i < v2.size(); i++)
	{
		cout << v2[i] << " ";
	}
	cout << endl;
}

(5)vector迭代器失效

迭代器的主要作用就是让算法能够不用关心底层数据结构,其底层实际就是一个指针或被封装的指针,vector的迭代器就是原生态指针T*,因此迭代器失效就是迭代器底层对应指针所指向的空间销毁了,而使用一块已经被释放的空间,如果继续使用已经失效的迭代器,程序可能会崩溃

下面是可能导致迭代器失效的操作

①引起底层改变的操作

resize、reserve、insert、assign、push_back等可能引起扩容的函数

这里拿resize来举例

cpp 复制代码
void test1()
{
	vector<int> v{ 1,2,3,4,5,6 };
	auto it = v.begin();
	v.resize(100, 0);
	while (it != v.end())
	{
		cout << *it << " ";
		++it;
	}
	cout << endl;
}

包括上面提到的其他函数,因为需要空间的增大,所以vector需要扩容,而vector扩容的操作是开辟新空间,拷贝数据到新空间,销毁旧空间,而寄存器it指向的位置是旧空间的位置,所以会出现操作已经被释放的空间的问题

解决方法是扩容之后重新赋值it

②指定元素的删除操作
cpp 复制代码
void test2()
{
	vector<int> v{ 1,2,3,4,5 };
	auto pos = find(v.begin(), v.end(), 3);
	v.erase(pos);
	cout << *pos << endl;
}

当使用erase删除元素时,所有在 erase() 之后的迭代器(包括 erase() 使用的迭代器)都会变得无效。这意味着一旦 pos 被用于 erase() 操作,pos 就不能再被用来访问或解引用任何元素了

③string类似于vector

string在上述过程之后,迭代器也会失效,原因相同,解决办法相同,性质相似

3、vector的优越性

杨辉三角问题

对于这个杨辉三角问题,我们需要一个二维数组,用C语言来写的话稍微的复杂一些,需要malloc一个指针数组,然后指针数组的指针指向一个一维数组

对于C++来说,我们需要一个vector<vector< int>>

最上面的_a的类型是vector< int>*

中间的_a的类型是int *

cpp 复制代码
class Solution {
public:
    vector<vector<int>> generate(int numRows)//numRows是杨辉三角行数 
    {
        vector<vector<int>> vv;
        vv.resize(numRows);//扩容numRows行
        for(size_t i = 0;i < vv.size();i++)
        {
            vv[i].resize(i+1,0);//将每一行所有的数字置为0
            vv[i][0] = vv[i][vv[i].size() - 1] = 1;//将三角两边的数字全部置为1
        }

        for(size_t i = 0;i < vv.size();i++)
        {
            for(size_t j = 0;j < vv[i].size();j++)
            {
            	if(vv[i][j] == 0)
            	{
                	vv[i][j] = vv[i-1][j]+vv[i-1][j-1];
                	//将所有不在三角两边的按照杨辉三角的原则相加得数
            	}
            }
        }
        return vv;
    }
};

今日分享就到这里了~

相关推荐
Scott9999HH4 小时前
【IIoT流量实战】蒸汽管道阀门全关却仍有流量?用 Python 实现涡街信号 FFT 频谱分析与温压全补偿积算网关,深度拆解靠谱的涡街流量计厂家硬核技术标准
开发语言·python
2401_841495645 小时前
【操作系统】进程同步与互斥实验报告
c++·算法·操作系统·进程·并发·同步·互斥
fqbqrr5 小时前
2607C++,soui与安卓
c++·soui
码智社5 小时前
AES加密原理详解及Java实现加解密实战
java·开发语言
AI云海5 小时前
python 列表、元组、集合和字典
开发语言·python
克里斯蒂亚诺更新5 小时前
ruoyi角色权限的对应关系
笔记
萧瑟余晖6 小时前
JDK 26 新特性详解
java·开发语言
马优晨7 小时前
Freemarker 完整讲解(后端 Java 模板引擎)
java·开发语言·freemarker·freemarker 完整讲解·freemarker模板引擎
a1117768 小时前
2FA 验证码生成器(github登录验证 app)
笔记·学习
我的xiaodoujiao8 小时前
API 接口自动化测试详细图文教程学习系列32--Allure测试报告2
python·学习·测试工具·pytest