STL库——Vector常见使用接口

一、介绍

1. vector是表示可变大小数组的序列容器,就像数组一样,vector也采用的连续存储空间来存储元素。也就是意味着可以采用下标对vector的元素 进行访问,和数组一样高效。但是又不像数组,它的大小是可以动态改变的,而且它的大小会被容器自动处理。

原先数组的本质也是对一个个整形进行数据管理,可以想象成一个表格,由于需要管理的数据比起单个整形,现实情况更加的复杂和庞大,因此其作用也需要扩大,可以将其想象成一个笔记本,被开一个空间则表示笔记本有多少页,统一管理一个相同类型的数据,当然如果系统更为复杂的情况,则可以往更大的系统去想象

2.本质讲,vector使用动态分配数组来存储它的元素。当新元素插入时候,这个数组需要被重新分配大小为了增加存储空间。其做法是,分配一个新的数组,然后将全部元素移到这个数组。就时间而言,这是 一个相对代价高的任务,因为每当一个新的元素加入到容器的时候,vector并不会每次都重新分配大小。

3.vector分配空间策略:vector会分配一些额外的空间以适应可能的增长,因为存储空间比实际需要的存 储空间更大。不同的库采用不同的策略权衡空间的使用和重新分配。但是无论如何,重新分配都应该是 对数增长的间隔大小,以至于在末尾插入一个元素的时候是在常数时间的复杂度完成的。因此,vector占用了更多的存储空间,为了获得管理存储空间的能力,并且以一种有效的方式动态增 长。与其它动态序列容器相比(deque, list and forward_list), vector在访问元素的时候更加高效,在末 尾添加和删除元素相对高效。对于其它不在末尾的删除和插入操作,效率更低。比起list和forward_list 统一的迭代器和引用更好。

二、常见接口及其使用

1.vector的定义

构造函数声明 接口说明
vector() 无参构造
vector(size_type n, const value_type& val = value_type()) 构造并初始化n个val
vector (InputIterator first, InputIterator last) 用迭代器初始化
vector (const vector& x) 拷贝构造
    vector first;                                // empty vector of ints
    vector second(4, 100);                       // four ints with value 100
    vector third(second.begin(), second.end());  // iterating through second
    vector fourth(third);                       // a copy of third

2.vector iterator的使用

iterator的使用 接口说明
begin+end begin获取第一个数据位置的iterator,end获取最后一个数据下一个位置的iterator
rbegin+end rbegin获取最后一个数据位置的reverse_iterator,end获取第一个数据前一个位置的reserve_iterator
void PrintVector(const vector& v)
{
	// const对象使用const迭代器进行遍历打印
	vector::const_iterator it = v.begin();
	while (it != v.end())
	{
		cout << *it << " ";
		++it;
	}
	cout << endl;
}

迭代器失效问题

对于vector可能会导致其迭代器失效的操作有:

1. 会引起其底层空间改变的操作,都有可能是迭代器失效,比如:resize、reserve、insert、assign、 push_back等。

2. 指定位置元素的删除操作--erase,删除操作在vs编译器认为,一旦执行,则原有迭代器视为失效
3. 与vector类似,string在插入+扩容操作+erase之后,迭代器也会失效。

迭代器失效解决办法:在使用前,对迭代器重新赋值即可。

3.vector空间管理接口

容量空间 接口说明
size 获取数据个数
capacity 获取容量大小
empty 判断是否为空

resize

改变vector的size,必要时会扩容,但不会缩容
reserve 改变vector的capacity的大小,必要是会扩容,一般不缩容

4.vector的增删查改

增删查改 接口说明
push_back 尾插
pop_back 尾删
find

查找(vector接口内没有自带的查找接口,需要时常用算法模块的查找功能),传参传迭代器,找到返回对应迭代器位置,找不到返回end的位置

insert 在pos之前插入val值
erase 删除pos位置的数据
swap 交换两个vector的数据空间
operator[ ] 像数组一样访问
void TestVector5()
{
	// 使用列表方式初始化,C++11新语法
	vector 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::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使用这两种遍历方式是比较便捷的。

三、相关的OJ题

1.只出现一次的数字(一)

题目链接:

​​​​​​力扣(LeetCode)官网 - 全球极客挚爱的技术成长平台

题目描述:

在一组数字中,除了一个数字是单独出现的,其余都是成双出现的,要求找到那个单独的数字。

解题思路:

全部异或一起就能找到那个数字

参考代码:

class Solution {
public:
    int singleNumber(vector& nums) 
    {
        int ret = 0;
        for(auto ch: nums)
        {
            ret^=ch;
        }
        return ret;
    }
};

2.杨辉三角

题目链接:

118. 杨辉三角 - 力扣(LeetCode)

题目描述:

给一个数字表示杨辉三角的层级数,需要返回一个类似于二维数组的结构去表示杨辉三角

解题思路:

首先先构造出杨辉三角的结构,可以用vector类型去初始化出相应的结构,然后在对数据进行处理

代码参考:

class Solution {
public:
    vector> generate(int numRows) 
    {
        vector> vvi;
        vvi.resize(numRows);
        for(int i = 0;i

3.电话号码字母组合

题目链接:

17. 电话号码的字母组合 - 力扣(LeetCode)

题目描述:

数字“2-9”对应着一串字母,题目给定一串数字字符串,要求得到对应字母的全排列组合

解题思路:

STL库——Vector常见使用接口_第1张图片

这里画出部分逻辑,将数字先转化成字母串,对字母串每一个都单独往下递归,将递归至最后一层的结果记录下来,最终将所有组合完成递归后结束。

参考代码:

class Solution 
{
    string num_let[10] = {"","","abc","def","ghi","jkl","mno","pqrs","tuv","wxyz"};
public:
    //递归的参数设计上,第一个参数是数字字符,第二个di是用于在递归过程中控制字母字符是第几层的参数
    //第三个参数是用于在递归过程中记录下每次完成一次排列后的结果,第四个参数则是每次完成单趟排列后,统一存起来,用于返回的
    //因此,第一个参数和第四个参数采用的是传引用

    void letterCom(string& s_num,int di,string tmp,vector& ret)
    {
        if(di == s_num.size())//递归的结束条件,结束时将单次排列的结果存到ret中
        {
            ret.push_back(tmp);
            return;
        }
        //先将每一层对应的字母串取出来
        int num = s_num[di] - '0';
        string s_letter= num_let[num];
        //每一个都逐一向下递归
        for(auto ch: s_letter)
        {
            letterCom(s_num,di+1,tmp+ch,ret);
        }
    }

    vector letterCombinations(string digits) 
    {


        vector ret;//用于存放返回的结果
        if(digits == "")//这里是考虑到空数字字符,则直接返回空
        {
            return ret;
        }
        letterCom(digits,0,"",ret);//递归的参数不止一个digits,因此要单独用一个函数实现递归
        return ret;

    }
};

总结

本篇对vector的常用接口进行了整理介绍,并且整理了相关的OJ题,用于练习熟悉vector的使用。

你可能感兴趣的:(c++,开发语言)