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) | 使用迭代器进行初始化构造 |

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

cpp 复制代码
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的迭代器使用代码演示:

cpp 复制代码
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;

测试函数:

cpp 复制代码
//  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容器的增删查改代码演示:

cpp 复制代码
//  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;
}
相关推荐
西岸行者5 天前
学习笔记:SKILLS 能帮助更好的vibe coding
笔记·学习
悠哉悠哉愿意5 天前
【单片机学习笔记】串口、超声波、NE555的同时使用
笔记·单片机·学习
别催小唐敲代码5 天前
嵌入式学习路线
学习
毛小茛5 天前
计算机系统概论——校验码
学习
babe小鑫5 天前
大专经济信息管理专业学习数据分析的必要性
学习·数据挖掘·数据分析
winfreedoms5 天前
ROS2知识大白话
笔记·学习·ros2
在这habit之下5 天前
Linux Virtual Server(LVS)学习总结
linux·学习·lvs
我想我不够好。5 天前
2026.2.25监控学习
学习
im_AMBER5 天前
Leetcode 127 删除有序数组中的重复项 | 删除有序数组中的重复项 II
数据结构·学习·算法·leetcode
CodeJourney_J5 天前
从“Hello World“ 开始 C++
c语言·c++·学习