c++领域展开第十六幕——STL(vector容器的了解以及各种函数的使用)超详细!!!!

文章目录

前言

在c++专栏的上一篇博客我们详细讲解了string类的模拟实现

同时在模拟实现过程中也学会了很多

stl的学习就是:能用,明理,能扩展

今天我们来了解 stl 的另外一个容器------vector

fellow me

一、vector的介绍和使用

1.1 vector的介绍

vector

文档链接如上

文档里面详细介绍了vector

vector有关的 成员函数以及功能都能找到

1.2 vector的使用

学习vector的时候可以多翻翻文档,便于更好的理解

1.2.1 vector的定义

constructor------------------构造函数声明接口说明

vector()(重点)------------无参构造

vector(size_type n, const value_type& val =value_type())------------构造并初始化n个val

vector (const vector& x); (重点) ------------------------拷贝构造

vector (InputIterator first, InputIterator last);------------ 使用迭代器进行初始化构造

代码展示:

cpp 复制代码
 	vector<int> first;                                // 无参构造
    vector<int> second(4, 100);                       // 构造并初始化 4 个 val
    vector<int> third(second.begin(), second.end());  // 使用迭代器进行初始化构造
    vector<int> fourth(third);                       //  拷贝构造

1.2.2 vector iterator 的使用

iterator的使用------------接口说明
begin + end(重点)

获取第一个数据位置的iterator/const_iterator, 获取最后一个数据的下一个位置的iterator/const_iterator
rbegin + rend

获取最后一个数据位置的reverse_iterator,获取第一个数据前一个位置的reverse_iterator


代码展示:

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;
}
cpp 复制代码
	// 使用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;

1.2.3 vector的空间增长问题

容量空间------------接口说明
size ------------------------获取数据个数
capacity ------------------获取容量大小
empty ---------------------判断是否为空
resize(重点) ---------改变vector的size
reserve (重点) ------改变vector的capacity

  1. capacity的代码在vs和g++下分别运行会发现,vs下capacity是按1.5倍增长的,g++是按2倍增长的。这个问题经常会考察,不要固化的认为,vector增容都是2倍,具体增长多少是根据具体的需求定义的。vs是PJ版本STL,g++是SGI版本STL。
  2. reserve只负责开辟空间,如果确定知道需要用多少空间,reserve可以缓解vector增容的代价缺陷问题。
  3. resize在开空间的同时还会进行初始化,影响size。

代码展示:

cpp 复制代码
// 可以试着运行下面代码
// reisze(size_t n, const T& data = T())
// 将有效元素个数设置为n个,如果时增多时,增多的元素使用data进行填充
// 注意:resize在增多元素个数时可能会扩容
void TestVector1()
{
	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);

	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();
	for (int i = 0; i < 100; ++i) 
	{
		v.push_back(i);
		if (sz != v.capacity()) 
		{
			sz = v.capacity();
			cout<< sz << '\n';
		}
	}
}

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

1.2.4 vector的增删改查

vector增删查改------------------ 接口说明
push_back(重点) ------------尾插
pop_back (重点) ------------ 尾删
insert ------------------------------ 在position之前插入val
erase ------------------------------删除position位置的数据
swap ------------------------------交换两个vector的数据空间
operator[] (重点) ------------像数组一样访问

cpp 复制代码
// 尾插和尾删: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);  //  vector 的 swap使用

	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;
}

二、vector在 oj 中的使用

只出现一次的数

只出现一次的数 I

还是比较简单的,就是按位异或就行,重复的元素按位异或之后就变成 0 了,只剩下出现一次的元素

cpp 复制代码
class Solution 
{
public:
    int singleNumber(vector<int>& nums) 
    {
        int value = 0;
        for(auto e : nums)
        {
            value ^= e;
        }
        return value;
    }
};

删除有序数组中的重复项

删除有序数组中的重复项

还是比较简单的,双指针完美解决,不知道的可以去我的------code ability 专栏看看

cpp 复制代码
class Solution 
{
public:
    int removeDuplicates(vector<int>& nums) //前后指针
    {
        int n = nums.size();
        int left = 0;
        for(int right = 1; right < n; right++)
        {
            if(nums[right] != nums[left])
            {
                if(right == ++left)
                continue;
                else
                {
                    nums[left] = nums[right];
                }
            }
        }
        return left+1;
    }
};

杨辉三角

杨辉三角

这里有个实时扩容的问题, 因为杨辉三角每一行的个数都不一样

其他的处理就比较简单了,话不多说,看代码

cpp 复制代码
class Solution {
public:
    vector<vector<int>> generate(int numRows) 
    {
        vector<vector<int>>  vv(numRows);
        for(int i = 0; i < numRows; i++)
        {
            vv[i].resize(i + 1, 1);
        }
        for(int i = 2; i < vv.size(); i++)
        {
            for(int j = 1; j < vv[i].size() - 1; j++)
            {
                vv[i][j] = vv[i - 1][j] + vv[i - 1][j - 1];
            }
        }
        return  vv; 
    }
};

其实写了几道题目下来,vector和数组的用法其实差不多 ,但是vector还是会好一些

毕竟有了封装 ,使得很多东西都标准化 ,同时作为容器 ,在后面学习配接器的时候还是很爽的

总结

今天认识了vector以及vector的使用,学习vector的第一步算是到这里啦

下一篇博客就是来深究探讨vector,自己模拟实现一遍

不要走开,小编持续更新中~~~~

相关推荐
jyan_敬言2 分钟前
【C++】入门基础(二)引用、const引用、内联函数inline、nullptr
c语言·开发语言·数据结构·c++·青少年编程·编辑器
UpUpUp……3 分钟前
模拟String基本函数/深浅拷贝/柔性数组
开发语言·c++·算法
奥顺互联V4 分钟前
如何处理PHP中的编码问题
android·开发语言·php
*.✧屠苏隐遥(ノ◕ヮ◕)ノ*.✧26 分钟前
C语言_数据结构总结9:树的基础知识介绍
c语言·开发语言·数据结构·b树·算法·visualstudio·visual studio
好看资源平台26 分钟前
加密算法逆向与HOOK技术实战
开发语言·python
byxdaz29 分钟前
QT编程之QGIS
开发语言·qt
烂蜻蜓33 分钟前
深入理解 HTML 中的<div>和元素:构建网页结构与样式的基石
开发语言·前端·css·html·html5
Honeysea_701 小时前
常用的Python库
开发语言·python·机器学习·计算机视觉·ai·自然语言处理
编程梦想记1 小时前
Python在数据处理中的应用:从入门到精通
开发语言·python·信息可视化
字节源流1 小时前
【SpringMVC】常用注解:@PathVariable
java·开发语言·servlet