当前位置: 首页 > article >正文

vector容器的学习

1.vector的介绍和使用

1.1vector的介绍

vector的介绍文档:cplusplus.com/reference/vector/vector/

使用STL的三个境界:能用,明理,能扩展、那么我们接下来就学习vector,我们也将按照这个方法来学习。

1.2vector的使用

在学习vector得我时候我们需要对应着相应的文档来学习:cplusplus.com/reference/vector/vector/

vector在实际中非常的重要,在实际中我们熟悉一些常见的接口就可以了,下面我们列出了一些常见的接口 :

大部分函数接口都插入有超链接

1.2.1vector的定义
 

construct(构造函数声明)接口说明
vector()(重点)无参数构造
被vector(size_type n, const vaule_type& val = value_type())构造并初始化n个val
vector(const vector& x)(重点)拷贝构造
vector(InputIterator first, InputIterator last)使用迭代器进行初始化构造

以下为相应的测试函数,感兴趣的小伙伴可以 自己去验证一下:

int TestVector1()
{
    // constructors used in the same order as described above:
    vector<int> first;                                // empty vector of ints
    vector<int> second(4, 100);                       // four ints with value 100
    vector<int> third(second.begin(), second.end());  // iterating through second
    vector<int> fourth(third);                       // a copy of third

    // 下面涉及迭代器初始化的部分,我们学习完迭代器再来看这部分
    // the iterator constructor can also be used to construct from arrays:
    int myints[] = { 16,2,77,29 };
    vector<int> fifth(myints, myints + sizeof(myints) / sizeof(int));

    cout << "The contents of fifth are:";
    for (vector<int>::iterator it = fifth.begin(); it != fifth.end(); ++it)
        cout << ' ' << *it;
    cout << '\n';

    return 0;
}

1.2.2vector iterator的使用

iterator的使用接口说明
begin+end(重点)获取第一个数据的位置的iterator/const_iterator, 获取最后一个数据的下一个位置的iterator/const_iterator
rbegin()+rend()获取第一个数据的位置的reverae_iterator, 获取最后一个位置的下一个位置的reverse_literator

 

 vector的迭代器使用代码演示:

void PrintVector(const vector<int>& v)
{
	// const对象使用const迭代器进行遍历打印
	vector<int>::const_iterator it = v.begin();
	while (it != v.end())
	{
		cout << *it << " ";
		++it;
	}
	cout << endl;
}

void TestVector2()
{
	// 使用push_back插入4个数据
	vector<int> v;
	v.push_back(1);
	v.push_back(2);
	v.push_back(3);
	v.push_back(4);

	// 使用迭代器进行遍历打印
	vector<int>::iterator it = v.begin();
	while (it != v.end())
	{
		cout << *it << " ";
		++it;
	}
	cout << endl;

	// 使用迭代器进行修改
	it = v.begin();
	while (it != v.end())
	{
		*it *= 2;
		++it;
	}

	// 使用反向迭代器进行遍历再打印
	// vector<int>::reverse_iterator rit = v.rbegin();
	auto rit = v.rbegin();
	while (rit != v.rend())
	{
		cout << *rit << " ";
		++rit;
	}
	cout << endl;

	PrintVector(v);
}

 1.2.3vector的空间增长问题

容量空间接口说明
size获取数据的个数
capacity获取容器此时的容量
empty判断此时容器是否为空
resize(重点)改变vector的size
reserve(重点)改变vector的capacity
  • capacity的代码在vs和g++下分别运行会发现,vs下的capacity是按照1.5倍增长的,g++时按照2倍增长的。这个问题就经常被考察,不要固化的认为,vector就是以两倍进行增容的,具体增长多少是根据具体的需求进行定义的。vs时PJ版本的STL,g++时SGI版本的STL.
  • reverse只负责派皮空间,如果确定知道需要多少的空间,reserve·可以缓解vector增容的代价缺陷问题。
  • resize在开辟空间的时候还会进行初始化,影响size;

测试函数:


//  vector的resize 和 reserve

// reisze(size_t n, const T& data = T())
// 将有效元素个数设置为n个,如果时增多时,增多的元素使用data进行填充
// 注意:resize在增多元素个数时可能会扩容
void TestVector3()
{
	vector<int> v;

	// set some initial content:
	for (int i = 1; i < 10; i++)
		v.push_back(i);

	v.resize(5);
	v.resize(8, 100);
	v.resize(12);

	cout << "v contains:";
	for (size_t i = 0; i < v.size(); i++)
		cout << ' ' << v[i];
	cout << '\n';
}

// 测试vector的默认扩容机制
// vs:按照1.5倍方式扩容
// linux:按照2倍方式扩容
void TestVectorExpand()
{
	size_t sz;
	vector<int> v;
	sz = v.capacity();
	cout << "making v grow:\n";
	for (int i = 0; i < 100; ++i) 
	{
		v.push_back(i);
		if (sz != v.capacity()) 
		{
			sz = v.capacity();
			cout << "capacity changed: " << sz << '\n';
		}
	}
}

// 往vecotr中插入元素时,如果大概已经知道要存放多少个元素
// 可以通过reserve方法提前将容量设置好,避免边插入边扩容效率低
void TestVectorExpandOP()
{
	vector<int> v;
	size_t sz = v.capacity();
	v.reserve(100);   // 提前将容量设置好,可以避免一遍插入一遍扩容
	cout << "making bar grow:\n";
	for (int i = 0; i < 100; ++i) 
	{
		v.push_back(i);
		if (sz != v.capacity())
		{
			sz = v.capacity();
			cout << "capacity changed: " << sz << '\n';
		}
	}
}

1.2.3vector增删查改

vector增删查改接口说明
push_back(重点)尾插
pop_back(重点)尾删
find查找(注意这个是算法模块实现的不是vector的成员接口)
insert在position位置插入val
erase删除position位置的数据
swap交换两个vector的数据空间
operator[](重点)像数组那样访问数据

vector容器的增删查改代码演示:
 


//  vector的增删改查

// 尾插和尾删:push_back/pop_back
void TestVector4()
{
	vector<int> v;
	v.push_back(1);
	v.push_back(2);
	v.push_back(3);
	v.push_back(4);

	auto it = v.begin();
	while (it != v.end()) 
	{
		cout << *it << " ";
		++it;
	}
	cout << endl;

	v.pop_back();
	v.pop_back();

	it = v.begin();
	while (it != v.end()) 
	{
		cout << *it << " ";
		++it;
	}
	cout << endl;
}

// 任意位置插入:insert和erase,以及查找find
// 注意find不是vector自身提供的方法,是STL提供的算法
void TestVector5()
{
	// 使用列表方式初始化,C++11新语法
	vector<int> v{ 1, 2, 3, 4 };

	// 在指定位置前插入值为val的元素,比如:3之前插入30,如果没有则不插入
	// 1. 先使用find查找3所在位置
	// 注意:vector没有提供find方法,如果要查找只能使用STL提供的全局find
	auto pos = find(v.begin(), v.end(), 3);
	if (pos != v.end())
	{
		// 2. 在pos位置之前插入30
		v.insert(pos, 30);
	}

	vector<int>::iterator it = v.begin();
	while (it != v.end()) 
	{
		cout << *it << " ";
		++it;
	}
	cout << endl;

	pos = find(v.begin(), v.end(), 3);
	// 删除pos位置的数据
	v.erase(pos);

	it = v.begin();
	while (it != v.end()) {
		cout << *it << " ";
		++it;
	}
	cout << endl;
}

// operator[]+index 和 C++11中vector的新式for+auto的遍历
// vector使用这两种遍历方式是比较便捷的。
void TestVector6()
{
	vector<int> v{ 1, 2, 3, 4 };

	// 通过[]读写第0个位置。
	v[0] = 10;
	cout << v[0] << endl;

	// 1. 使用for+[]小标方式遍历
	for (size_t i = 0; i < v.size(); ++i)
		cout << v[i] << " ";
	cout << endl;

	vector<int> swapv;
	swapv.swap(v);

	cout << "v data:";
	for (size_t i = 0; i < v.size(); ++i)
		cout << v[i] << " ";
	cout << endl;

	// 2. 使用迭代器遍历
	cout << "swapv data:";
	auto it = swapv.begin();
	while (it != swapv.end())
	{
		cout << *it << " ";
		++it;
	}

	// 3. 使用范围for遍历
	for (auto x : v)
		cout << x << " ";
	cout << endl;
}


http://www.kler.cn/a/402403.html

相关文章:

  • 解读AI智能招聘如何精准高效解决企业人才缺口
  • 【机器学习】机器学习中用到的高等数学知识-6. 组合数学 (Combinatorics)
  • 【机器学习】机器学习中用到的高等数学知识-7.信息论 (Information Theory)
  • element plus el-table 简单分页组件
  • Django5 2024全栈开发指南(三):数据库模型与ORM操作
  • 4.4.5 timer中断流向Linux(从interrupt log回放)
  • 【机器学习】在泊松分布中,当λ值较大时,其近似正态分布的误差如何评估?
  • vue中v-if和v-show的区别
  • 嵌入式驱动面试总结
  • 景联文科技:以全面数据处理服务推动AI创新与产业智能化转型
  • 【第二十一周】网络爬虫实践
  • 深入探索淘宝API:高效实现关键字搜索商品列表的技术实践
  • 企业软文推广如何巧妙借力优质媒体,让品牌在市场中脱颖而出?媒介盒子分享
  • 2411rust,1.81,1.82
  • Charles抓https包-配置系统证书(雷电)
  • Elasticsearch:更好的二进制量化(BBQ)对比乘积量化(PQ)
  • 自我通信11
  • STM32学习笔记----UART、IIC、SPI的区别
  • 鸿蒙NEXT开发-用户通知服务的封装和文件下载通知
  • Vue 3 中使用 `<script setup>` 语法糖实现模板插值表达式