【ONE·C++ || vector (一)】

news2025/1/22 12:51:25

总言

  学习笔记,慢慢补充。

文章目录

  • 总言
  • 1、整体介绍:
  • 2、常用各种接口介绍
    • 2.1、vector的基本结构:构造、析构、赋值
      • 2.1.1、总体情况预览
      • 2.1.2、各项函数使用演示
    • 2.2、vector增删查改相关
      • 2.2.1、增删查改总览
      • 2.2.2、如何在vector中插入、删除、遍历数据
      • 2.2.3、front、back函数
    • 2.3、vector扩容相关
      • 2.3.1、容量问题总览
      • 2.3.2、resize、reserve函数介绍
    • 2.4、其它一些函数介绍
      • 2.4.1、find、insert函数介绍
      • 2.4.2、erase函数介绍
      • 2.4.3、vector排序问题:sort
    • 2.5、一些现象、问题说明
      • 2.5.1、一个问题讨论:vector存储char字符与string的比较
      • 2.5.2、vector与string结合使用:vector< string >
  • 3、相关练习题:
    • 3.1、只出现一次的数字
    • 3.2、杨辉三角:vector<vector< int >> 嵌套使用

  
  

1、整体介绍:

   该文章参考网站是cplusplus.com。
在这里插入图片描述
  1、vector是类模板,其有两个模板参数class T class Alloc = allocator<T>
  2、 class Alloc = allocator<T>:空间配置器(内存池)。默认配置了一个缺省参数,由库提供这个内存池。若自己有设计想法,也可自己显示实现。

  
  

2、常用各种接口介绍

2.1、vector的基本结构:构造、析构、赋值

2.1.1、总体情况预览

  1)、构造函数总览

在这里插入图片描述
在这里插入图片描述
  
  
  2)、析构函数总览
   vector的析构函数,出了作用域自动调用。
在这里插入图片描述

  
  
  3)、赋值运算符重载总览
   赋值运算符重载就涉及到后续深浅拷贝的问题。
在这里插入图片描述

  
  4)、小结
   上述几个函数中,
      ①对构造函数,使用最多的是无参构造、拷贝构造。
      ②对析构函数调用默认的即可,故不用太过理会。
      ③对赋值运算符重载,偶尔用到。
  
  
  
  

2.1.2、各项函数使用演示

  1)、演示构造函数:

  ①由下述代码可知,vector是一个类模板,因此需要显示实例化(详细学习请见模板初阶)。

template < class T, class Alloc = allocator<T> > 
class vector;

  ②以下即为常见的vector的构造用法:

void test_vector01()
{
	vector<int> v1;//无参构造
	vector<int> v2(5, 10);//n个val
	vector<int> v3(v2);//拷贝构造
}

  ③通过调试观测如下:需要注意的是,对于vector的构造函数,后续我们在模拟实现时仍旧要解决深浅拷贝的问题。

在这里插入图片描述

  
  
  
  

2.2、vector增删查改相关

2.2.1、增删查改总览

在这里插入图片描述

  
  

2.2.2、如何在vector中插入、删除、遍历数据

  1)、对数据插入、删除:
   根据上述总览,目前我们知道可以使用push_backpop_backinserterase来达成数据的插入删除。

		vector <int> v1;//构造一个vector,名为v1
		v1.push_back(1);//尾插
		v1.push_back(2);
		v1.push_back(3);
		v1.push_back(4);

  
  2)、对数据的遍历:

在这里插入图片描述 方式一:下标+[ ]

   相关函数:
在这里插入图片描述
在这里插入图片描述
   代码演示:

		//遍历演示
		for (size_t i = 0; i < v1.size(); ++i)//vector::size
		{
			cout << v1[i] << " ";//vector::operator[]
		}
		cout << endl;

		//下标访问,遍历自增
		for (size_t i = 0; i < v1.size(); ++i)
		{
			v1[i]++;
		}

		//再次遍历
		for (size_t i = 0; i < v1.size(); ++i)//vector::size
		{
			cout << v1[i] << " ";//vector::operator[]
		}
		cout << endl;

在这里插入图片描述
  
  

在这里插入图片描述 方式二:迭代器

   代码演示:

		//使用迭代器遍历:需要注意的是这里迭代器对应的vector使用了模板参数
		vector<int>::iterator it = v1.begin();
		while (it != v1.end())
		{
			cout << *it << " ";
			++it;
		}
		cout << endl;

在这里插入图片描述
   涉及函数:
在这里插入图片描述

   支持迭代器,就支持范围for:

		//使用范围for
		for (auto e : v1)
		{
			cout << e << " ";
		}
		cout << endl;

在这里插入图片描述

  
  

2.2.3、front、back函数

  1)、简介:
   获取vector首元素和尾元素。 关于front和back二者的使用请见下述练习3.2。

在这里插入图片描述

  

2.3、vector扩容相关

2.3.1、容量问题总览

在这里插入图片描述

  
  

2.3.2、resize、reserve函数介绍

  1)、扩容机制的验证

	//扩容机制验证
	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';
			}
		}
	}

  此处是以VS2019为例的运行结果:
在这里插入图片描述

  
  2)、reserve、rsize介绍
   在已知要插入的数据量的情况下,我们可以提前扩容:

	void TestVectorExpand()
	{
		size_t sz;
		vector<int> v;
		//v.resize(100);//resize在开空间的同时还会进行初始化,影响size。
		v.reserve(100);//reserve只负责开辟空间,可缓解vector增容的代价缺陷问题。
		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';
			}
		}
	}

   在上述场景中不能使用resize,因为resize在开辟空间的同时进行初始化数据。假如上述场景中使用了resize,相当于我已经在resize的帮助下拥有了100个数据,后续的for循环又为我提供了100个数据。
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

  
  

2.4、其它一些函数介绍

2.4.1、find、insert函数介绍

  1)、对algorithm
   在vector中,可以看到并没有单独的find函数,是因为我们完全可以用[ ]来做到,另者,如果有需要,algorithm库中提供了find函数。

在这里插入图片描述
  同理,vector也不像string一样提供流插入、流提取。因为我们对vector的一般是遍历访问,而string有整体打印字符串的需求。
  
  
  2)、对vector::insert
   vector中insert的用法说明:注意iterator position,其使用的是迭代器。

iterator is a member type, defined as a random access iterator type that points to elements.

在这里插入图片描述
  
  3)、使用演示

		vector <int> v1;//构造一个vector,名为v1
		v1.push_back(1);//尾插
		v1.push_back(2);
		v1.push_back(3);
		v1.push_back(4);

		//使用find在v1中查找值:范围[v1.begin(),v1.end()),val=3
		vector<int>::iterator pos = find(v1.begin(), v1.end(), 3);
		if (pos != v1.end())//检查是否找到相关值。此处find的last=v1.end()
		{
			v1.insert(pos,30);
		}
		//遍历:用于检测是否成功插入数据
		for (auto e : v1)
		{
			cout << e << " ";
		}
		cout << endl;

在这里插入图片描述
  
  
  4)、一个边界说明
   如下图,分析现象并说明原因:

在这里插入图片描述

   原因:在v1中寻找300,find返回结果为v1.end()下标,相当于尾插。
   说明:虽然此处没有明确报错现象,但使用find找到值后最好还是检查一下。
  
  

2.4.2、erase函数介绍

  1)、对erase
在这里插入图片描述

  2)、使用演示:

		vector <int> v1;//构造一个vector,名为v1
		v1.push_back(1);//尾插
		v1.push_back(2);
		v1.push_back(3);
		v1.push_back(4);

		//使用find在v1中查找值:范围[v1.begin(),v1.end()),val=3
		vector<int>::iterator pos = find(v1.begin(), v1.end(), 3);
		if (pos != v1.end())//检查是否找到相关值。此处find的last=v1.end()
		{
			v1.erase(pos);//删除单个元素
		}
		
		//遍历:用于检测是否成功插入数据
		for (auto e : v1)
		{
			cout << e << " ";
		}
		cout << endl;

在这里插入图片描述

  3)、不检查find返回值情况验证:
   如下图所示:报错。

在这里插入图片描述
  
  
  

2.4.3、vector排序问题:sort

  1)、基本介绍
   ①sort也是一个函数模板,其底层使用的原理是快排,默认排的是升序。
在这里插入图片描述
  
  2)、sort排升序

		//乱序
		vector <int> v1;
		v1.push_back(11);
		v1.push_back(23);
		v1.push_back(6);
		v1.push_back(1);
		v1.push_back(9);
		v1.push_back(7);
		v1.push_back(3);
		v1.push_back(15);
		//排升序
		sort(v1.begin(), v1.end());
		//遍历查看
		vector<int>::iterator it = v1.begin();
		while (it != v1.end())
		{
			cout << *it << " ";
			it++;
		}
		cout << endl;

在这里插入图片描述
  
  3)、sort排降序
   sort排降序涉及到 Compare comp仿函数,此处我们只需要学习使用方法:
   两个函数介绍:less、greater

		介绍:
		less也是一个类模板,int为此处需要的数据类型
		greater同上,但使用greater需要包含头文件<functional>。
		less不需要包含的这个头文件的原因是,sort默认升序。
		

		#include<functional>
		less<int> ls;
		greater<int> gt;
		
		//sort(v1.begin(), v1.end(), ls);
		sort(v1.begin(), v1.end(), gt);

在这里插入图片描述
  当然,上述只是一种写法介绍,也可以按照下述写法进行:

	sort(v1.begin(), v1.end(), greater<int>());

  此处相当于匿名对象的使用。

在这里插入图片描述

  
  
  4)、sort在string中的使用演示

		string s("hello string 1144579");
		sort(s.begin(), s.end());
		cout << s << endl;

   sort在string中是按照ASCII码排序的:

在这里插入图片描述

   也可以排降序:

		string s("hello string 1144579");
		sort(s.begin(), s.end(), greater<char>());
		cout << s << endl;

在这里插入图片描述

  
  
  

2.5、一些现象、问题说明

2.5.1、一个问题讨论:vector存储char字符与string的比较

   问题描述:

		vector<char> v;
		string s;

   上述二者有什么差异?能否用前者代替后者?
   回答:
   ①string中s后面默认追加\0;
   ②相比于vector,string中的相关函数比较多,实现功能也更全,比如+=(一个字符/字符串),流插入流提取,find(查字符串),比较大小、to_string等。
  
  
  

2.5.2、vector与string结合使用:vector< string >

		//void push_back (const value_type& val);
		//void push_back (const T& val);

		vector<string>strV;

		string str1("张龙");
		strV.push_back(str1);//深拷贝:push_back中val为什么要加&的原因

		strV.push_back(string("赵虎"));//匿名对象:push_back中val为什么要加const的原因

		strV.push_back("王朝");//日常使用习惯:隐式类型转换
		//for (auto str : strV)
		//{
		//	cout << str << endl;
		//}
		
		//1、这里也涉及一个深浅拷贝的问题,所以需要十分谨慎处理
		//2、如果不涉及改变内容,可以加上const
		for (const auto& str : strV)
		{
			cout << str << endl;
		}

在这里插入图片描述

  
  
  

3、相关练习题:

3.1、只出现一次的数字

   题源
在这里插入图片描述
   代码如下:

class Solution {
public:
    int singleNumber(vector<int>& nums) {
        int value=0;
        for(auto e:nums)
        {
            value^=e;//异或
        }
        return value;
    }
};

   要满足时间复杂度O(n),空间复杂度O(1),最简单的方式就是使用异或。
   其余不满足上述条件下,也可以使用排序遍历、直接遍历等方法。
  
  

3.2、杨辉三角:vector<vector< int >> 嵌套使用

   题源

在这里插入图片描述
  
   关键点: 理解vector<vector<int>> 的含义。
在这里插入图片描述

   代码如下:

class Solution {
public:
    vector<vector<int>> generate(int numRows) {

        vector<vector<int>> vv;//定义一个vector<vector<int>>类型的数据
        vv.resize(numRows);//第一次开辟空间:numRows,表示总行数(整体大小)
        for(size_t i=0;i<numRows;i++)//对每行预处理:空间大小、边界数值
        {
            vv[i].resize(i+1,0);//第二次开辟空间,表示初始化杨辉三角的每行大小
            vv[i].front()=vv[i].back()=1;//杨辉三vv.size()角每行首尾数据为1

            //vv[i].resize(i+1,1);//上述代码也可以合并为一行实现
        }

        for(size_t i=2;i<vv.size();i++)//对每行的中间数据做处理:第i行第j个元素=第i-1行第j=1个元素+第i-1行第j个元素
        {
            for(size_t j=1;j<i;j++)
            {
                vv[i][j]=vv[i-1][j-1]+vv[i-1][j];
            }
        }

        return vv;
    }
};

vv[i][j]的理解如下:双层嵌套
在这里插入图片描述

  
  
  
  
  
  

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/151656.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Kotlin之使用协程编写高效的并发程序

文章目录1.协程的基本用法2.更多的作用域构建器3.使用协程简化回调的写法协程属于Kotlin中非常有特色的一项技术&#xff0c;因为大部分编程语言中是没有协程这个概念的。那么什么是协程呢&#xff1f;它其实和线程有点相似&#xff0c;可以简单地将它理解成一种轻量级的线程。…

Linux学习入门

1、Linux简介 操作系统分类&#xff1a;桌面操作系统、、服务器操作系统、移动端操作系统、嵌入式操作系统桌面操作系统主要针对个人电脑&#xff0c;Linux在桌面操作系统的应用主要有国产操作系统&#xff0c;Ubuntu。服务器操作系统有windows和linux以及苹果&#xff0c;主流…

微信小程序是如何实现快速编译的?

过往中小企业或技术团队开发一个 App 的时间成本和人力成本居高难下&#xff0c;但是随着微信上线小程序&#xff0c;更像是为这部分群体打开了一扇天窗&#xff0c;此后小程序呈现出井喷式发展的状态&#xff0c;不仅微信&#xff0c;支付宝、百度、抖音等超级 App 都跟上步伐…

线程进阶

常见的锁策略乐观锁 vs 悲观锁乐观锁&#xff1a;预测锁竞争不是很激烈悲观锁&#xff1a;预测锁竞争会很激烈轻量级锁 vs 重量级锁轻量级锁加锁解锁开销比较小&#xff0c;效率更高重量级锁加锁解锁开销比较大&#xff0c;效率更低多数情况下&#xff0c;乐观锁&#xff0c;也…

在CSDN年收入竟达五位数?----大学生技术自媒体成长之路

前言&#xff1a; Hello大家好&#xff0c;我是Dream。 还有不到两周就要过年了&#xff0c;自己也马上迈入了21岁&#xff0c;感慨时间飞快&#xff0c;从19岁开始入驻C站&#xff0c;到现在也已经整整两年了&#xff0c;把自己最好的两年青春时光留在了CSDN&#xff0c;超百万…

定义输出格式的使用-printf()函数

目录&#x1f4d6;printf()函数简介格式化规定符格式控制特殊规定字符示例printf()函数简介 printf()函数是格式化输出函数, 一般用于向标准输出设备按规定格式输出信息。 printf()函数的调用格式为:printf("<格式化字符串>", <参量表>);这里看输出很简…

Lua入门学习

一、初识Lua脚本 Lua 是一种轻量小巧的脚本语言&#xff0c;用标准C语言编写并以源代码形式开放&#xff0c; 其设计目的是为了嵌入应用程序中&#xff0c;从而为应用程序提供灵活的扩展和定制功能。官网&#xff1a;https://www.lua.org/ 1、HelloWorld CentOS7默认已经安装…

什么是docker

文章目录简介Docker 架构特性局限Docker 是一个开源的应用容器引擎&#xff0c;让开发者可以打包他们的应用以及依赖包到一个可移植的镜像中&#xff0c;然后发布到任何流行的 Linux或Windows操作系统的机器上&#xff0c;也可以实现虚拟化。容器是完全使用沙箱机制&#xff0c…

〖产品思维训练白宝书 - 产品思维认知篇⑨〗- 像 产品经理 一样去思考解决问题

大家好&#xff0c;我是 哈士奇 &#xff0c;一位工作了十年的"技术混子"&#xff0c; 致力于为开发者赋能的UP主, 目前正在运营着 TFS_CLUB社区。 &#x1f4ac; 人生格言&#xff1a;优于别人,并不高贵,真正的高贵应该是优于过去的自己。&#x1f4ac; &#x1f4e…

数据结构:算法的初步认识

算法是解决特定问题求解步骤的描述&#xff0c;在计算机中表现为指令的有限序列&#xff0c;并且每条指令表示一个或多个操作。 什么是算法 要求你写一个求 123…100 结果的程序&#xff0c;你应该怎么写呢? 大多数人会马上写出下面的C语言代码(或者其他语言的代码): int a,…

seata的AT模式

seata 分布式事务解决方案 官网 &#xff1a; seata.io 事务模式&#xff1a; 名词 TC &#xff1a; transaction coordinator 事务协调者 维护全局事务 和 分支事务的状态&#xff0c;驱动全局事务提交或者回滚TM &#xff1a; transaction manager 事务管理器 定义全局事…

(考研湖科大教书匠计算机网络)第一章概述-第三节:计算机网络的定义、功能分类

文章目录一&#xff1a;计算机网络的定义&#xff08;1&#xff09;最简单定义&#xff08;2&#xff09;较好定义二&#xff1a;计算机网络功能三&#xff1a;计算机网络的分类&#xff08;1&#xff09;按照“覆盖范围”分类&#xff08;2&#xff09;按照“使用者”分类&…

【Linux学习】进程控制

&#x1f431;作者&#xff1a;一只大喵咪1201 &#x1f431;专栏&#xff1a;《Linux学习》 &#x1f525;格言&#xff1a;你只管努力&#xff0c;剩下的交给时间&#xff01; 在前面&#xff0c;我们学习了进程的相关概念&#xff0c;在这里本喵会给大家介绍如何控制进程。…

私人影院微信小程序源码,采用腾讯小程序云开发,包括影院动态,最新影讯,房间预约,后台预约管理,导出预约表格Excel数据等功能

功能介绍 私人影院是很多年轻人比较喜欢的地方&#xff0c;虽然空间小&#xff0c;但是他们喜欢在这样的空间里享受休闲的时光&#xff0c;通过提前预约订位&#xff0c;可以使商家和消费者节省时间&#xff0c;减少人力成本&#xff0c;大大方便业务的拓展&#xff0c;同时也…

Word控件Spire.Doc 【Table】教程(4):如何在C#、VB.NET中设置Word表格样式

Spire.Doc for .NET是一款专门对 Word 文档进行操作的 .NET 类库。在于帮助开发人员无需安装 Microsoft Word情况下&#xff0c;轻松快捷高效地创建、编辑、转换和打印 Microsoft Word 文档。拥有近10年专业开发经验Spire系列办公文档开发工具&#xff0c;专注于创建、编辑、转…

备战蓝桥杯数学基础:位运算理论

[TOC](目录)位运算概述位运算就是基于整数的二进制表示进行的运算&#xff0c;由于计算机内部就是以二进制来村塾数据&#xff0c;位运算是相当快的。基本的位运算共6种&#xff0c;分别为按位与、按位或、按位异或、按位取反、左移和右移与、或、异或这三者都是两数间的运算&a…

【算法刷题】栈与队列题型及方法归纳

栈与队列的特点 1、栈&#xff1a;FIFO 栈是仅能对其一端进行操作的结构&#xff0c;实现后进先出的效果。在C中采用容器适配器的方式实现栈。&#xff08;容器适配器实际上就是对某一类型的对象进行泛化&#xff0c;定义了这一类泛化对象的可进行操作的逻辑&#xff09; 什么…

上半年要写的博客文章22

这里写自定义目录标题欢迎使用Markdown编辑器新的改变功能快捷键合理的创建标题&#xff0c;有助于目录的生成如何改变文本的样式插入链接与图片如何插入一段漂亮的代码片生成一个适合你的列表创建一个表格设定内容居中、居左、居右SmartyPants创建一个自定义列表如何创建一个注…

极端尺度物体的显著性分割方法(SOD 新 SOTA)

Paper Link&#xff1a;http://cvteam.buaa.edu.cn/papers.htmlBackground&#xff1a;显著性物体分割在常规图像场景取得突破进展&#xff0c;在极端尺度物体场景仍面临挑战。图像前景物体分割是深度学习、计算机视觉等领域的研究热点&#xff0c;在机器视觉、智能交通、智慧医…

Mac 电脑磁盘空间释放记录

起因 点开钉钉页面就卡住&#xff0c;看了一下&#xff0c;光一个钉钉占到4G左右的内存&#xff0c;给钉钉发了工单&#xff0c;没人理我。又随手看了一下系统磁盘空间使用情况&#xff0c;发现快满了&#xff01;&#x1f613; 应用清单 我是一个应用的超轻度用户&#xff…