【C++第三阶段】STL初识

以下内容仅为当前认识,可能有不足之处,欢迎讨论!


文章目录

  • STL初步认识
    • vector存放内置数据类型
    • vector存放自定义数据类型
    • vector 嵌套容器


STL初步认识

回顾时,需要回答自己

①STL是什么?

②STL怎么用?

③STL优势是什么?

④STL是为了解决什么问题存在的技术?

为了提升代码的复用性,建立数据结构和算法的一套标准,诞生了STL。

STL=Standard Template Library=标准模板库。

STL广义上分为:①容器,②算法,③迭代器。其中,迭代器为容器和算法提供了桥梁,使得彼此有连接。

STL几乎所有代码采用了模板类或者模板函数。

STL六大组件

容器:各种数据结构,如vector,list,deque,set,map等,存放数据用的。

算法:常用算法,如sort,find,copy,for_each等。

迭代器:容器和算法之间的胶合剂。{我理解为桥梁}

仿函数:{重载函数小括号}:行为类似函数,可作为算法的某种策略。

适配器:多个参数传递,组装操作。——一种用来修饰容器或者仿函数或迭代器接口的东西。

空间配置器:容器用时,开辟到堆区,自动管理空间配置和管理。

容器&算法&迭代器之具体

容器作用:将运用最广泛的数据结构实现出来。

常用数据结构:数组,链表,树,栈,队列,集合,映射表等。

序列式容器{我理解为顺序数据结构}:强调值的排序,序列式容器中每个元素有固定位置。

关联式容器{我理解为链表}:二叉树结构,各元素之间没有严格的物理的顺序关系。

算法:

质变算法&非质变算法

质变算法:运算过程中更改区间元素的内容,例如拷贝,替换,删除等。

{我理解为对元素本身更改。}

非质变算法:运算过程中不会更改区间的元素内容,例如查找,计数,遍历,寻找极值等。

{我理解为对元素本身修改了。}

迭代器:提供方法,能够按照顺序访问容器所含各个元素,又无需暴露该容器的内部表示方式。

每个容器有其专属的迭代器。

迭代器使用类似于指针。先理解为迭代器。

image-20240402232812946

vector存放内置数据类型

vector遍历

容器:vector

算法:for_each

迭代器:vector<int>::iterator

vector一个简单案例,使用C++自带的模板实现数组,并且有三种方式遍历。

第一种方式易读,但冗余。

第二种方式适中。

第三种方式需要理解在说什么。

每一个容器都有自己的迭代器,迭代器是用来遍历容器中的元素。

v.begin()返回迭代器,这个迭代器指向容器中第一个数据。

v.end()返回迭代器,这个迭代器只想容器元素的最后一个元素的下一个位置。

vecotr<int>::iterator 拿到vector这种容器的迭代器类型。

image-20240403120043312

代码示例:

#include<iostream>
#include<string>
using namespace std;
#include"CommonArray.hpp"

#include<vector>
#include<algorithm>


void Method_A(vector<int> &myVec) {
	//通过迭代器访问容器数据
	vector<int>::iterator itBegin = myVec.begin();
	//起始迭代器,指向容器第一个元素
	vector<int>::iterator itEnd = myVec.end();
	//结束迭代器,指向容器最后一个元素的下一个位置

	//vector<int>::iterator 拿到vector<int>这种容器的迭代器类型
	while (itBegin != itEnd) {
		cout << *itBegin << endl;
		itBegin++;
		//起始指针+1
	}
}

void Method_B(vector<int>& myVec) {
	for (vector<int>::iterator it = myVec.begin(); it != myVec.end(); it++) {
		cout << *it << endl;
	}
}

//这个参数要写什么内容?
//因为是int类型的模板,所以现在是传入整型。
void Print(int element) {
	cout << element << endl;
}
//第三种遍历方式。利用STL提供的遍历算法。
//需要包含对应头文件。
void Method_C(vector<int>& myVec) {
	for_each(myVec.begin(), myVec.end(), Print);
}

void test0403() {
	//新建一个vector容器
	vector<int> myVec;
	myVec.push_back(15);
	myVec.push_back(25);
	myVec.push_back(35);
	myVec.push_back(45);

	//第一种方法
	cout << "使用第一种方法遍历" << endl;
	Method_A(myVec);
	//第二种方法
	cout << "\n使用第二种方法遍历" << endl;
	Method_B(myVec);
	//第三种方法
	cout << "\n使用第三种方法遍历" << endl;
	Method_C(myVec);
}


int main() {

	test0403();
	system("pause");
	return 0;
}

运行结果:

image-20240403121000600

vector存放自定义数据类型

存放自定义的数据类型。

仍然是把它当作一个指针来看待。需要注意的是,创建vector语句是:vector<自定义数据类型> 变量名;,而创建迭代器的语句是:vector<自定义数据类型>::iterator 变量名2=变量名.begin();

代码示例:

#include<iostream>
#include<string>
using namespace std;
#include"CommonArray.hpp"
#include<ostream>

#include<vector>
#include<algorithm>


//使用vector存放自定义数据类型
class Person {
public:
	Person(string name, int age) :person_name(name), person_age(age) {}
public:
	string person_name;
	int person_age;
};


ostream& operator<<(ostream& out, Person& person) {
	//cout << person.person_name << "の年龄是" << person->person_age << "." << endl;
	cout << person.person_name << "の年龄是" << person.person_age << "." << endl;
	return out;
}


ostream& operator<<(ostream& out, Person* person) {
	//cout << person.person_name << "の年龄是" << person->person_age << "." << endl;
	cout << person->person_name << "の年龄是" << person->person_age << "." << endl;
	return out;
}

void test0403() {
	Person Chandler("Chandler", 36);
	Person Ross("Ross", 35);
	Person Monica("Monica", 32);
	Person Febe("Febe", 33);
	Person Joey("Joey", 34);
	Person Rachel("Rachel", 33);
	//第一种方式,使用Person类型的数组
	vector<Person> Persons;
	Persons.push_back(Chandler);
	Persons.push_back(Ross);
	Persons.push_back(Monica);
	Persons.push_back(Febe);
	Persons.push_back(Joey);
	Persons.push_back(Rachel);

	//Person类型的容器
	cout << "Person类型的容器" << endl;
	for (vector<Person>::iterator per = Persons.begin(); per != Persons.end(); per++) {
		//第一种方式,per是指针,此时重写了左移运算符。
		//per指针,那么*取值,就取道了对应的值。
		
		cout << *per;
		
		//cout << per->person_name << "の年龄是" << per->person_age << "." << endl;
	}
	cout << endl;

	//如果是Person指针类型的容器
	vector<Person*> PersonPointer;
	//存放的是一组Person指针类型的数据,所以传入时要传地址
	PersonPointer.push_back(&Chandler);
	PersonPointer.push_back(&Ross);
	PersonPointer.push_back(&Monica);
	PersonPointer.push_back(&Febe);
	PersonPointer.push_back(&Joey);
	PersonPointer.push_back(&Rachel);

	cout << "Person指针类型的容器" << endl;
	//Person指针类型的容器
	for (vector<Person*>::iterator pp = PersonPointer.begin(); pp != PersonPointer.end(); pp++) {
		//pp为每一个元素的指针,取值后取得是每一个元素的地址,所以要取两次
		cout << *pp;
	}
}

int main() {

	test0403();
	system("pause");
	return 0;
}

运行结果:

image-20240403133417533

vector 嵌套容器

容器中另有一个容器。相当于二维数组。

代码实现:

#include<iostream>
#include<string>
using namespace std;
#include"CommonArray.hpp"
#include<ostream>

#include<vector>
#include<algorithm>

void test0403() {
	vector<vector<int>> vec;
	vector<int> tor1;
	vector<int> tor2;
	vector<int> tor3;
	vector<int> tor4;
	//分别向四个内层容器中添加元素。
	for (int i = 0; i < 4; i++) {
		tor1.push_back(i + 1);
		tor2.push_back(i + 2);
		tor3.push_back(i + 3);
		tor4.push_back(i + 4);
	}
	vec.push_back(tor1);
	vec.push_back(tor2);
	vec.push_back(tor3);
	vec.push_back(tor4);
	
	//遍历嵌套容器
	for (vector<vector<int>>::iterator vec_begin = vec.begin(); vec_begin != vec.end(); vec_begin++) {
		//对内层容器遍历,vec_begin是指向容器的指针,所以要用*解引用
		for (vector<int>::iterator tor_begin = (*vec_begin).begin(); tor_begin != (*vec_begin).end(); tor_begin++) {
			cout<<*tor_begin<<" ";
		}
		cout<<endl;
	}
	
}

int main() {

	test0403();
	system("pause");
	return 0;
}

运行结果:

在这里插入图片描述


以上是我的学习笔记,希望对你有所帮助!
如有不当之处欢迎指出!谢谢!

学吧,学无止境,太深了

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【简单讲解下WebSocket】

&#x1f308;个人主页:程序员不想敲代码啊 &#x1f3c6;CSDN优质创作者&#xff0c;CSDN实力新星&#xff0c;CSDN博客专家 &#x1f44d;点赞⭐评论⭐收藏 &#x1f91d;希望本文对您有所裨益&#xff0c;如有不足之处&#xff0c;欢迎在评论区提出指正&#xff0c;让我们共…

【DA-CLIP】test.py解读,调用DA-CLIP和IRSDE模型复原计算复原图与GT图SSIM、PSNR、LPIPS

文件路径daclip-uir-main/universal-image-restoration/config/daclip-sde/test.py 代码有部分修改 导包 import argparse import logging import os.path import sys import time from collections import OrderedDict import torchvision.utils as tvutilsimport numpy as…

ruoyi-nbcio-plus基于vue3的flowable流程元素选择区面板的升级修改

更多ruoyi-nbcio功能请看演示系统 gitee源代码地址 前后端代码&#xff1a; https://gitee.com/nbacheng/ruoyi-nbcio 演示地址&#xff1a;RuoYi-Nbcio后台管理系统 http://122.227.135.243:9666/ 更多nbcio-boot功能请看演示系统 gitee源代码地址 后端代码&#xff1a…

工业项目中你连SCADA都没见过?

什么是SCADA SCADA是一种监控和数据采集系统&#xff0c;全称是Supervisor.Contro.an.Dat.Acquisition。SCADA系统在工业项目中具有广泛应用&#xff0c;包括生产线监控、工艺控制、设备维护、能源管理、安全监控和产量跟踪等多个场景。通过实时监测、数据采集和远程控制等功能…

网络协议栈--数据链路层

目录 对比理解“数据链路层”和“网络层”一、认识以太网1.1 以太网帧格式1.2 认识MAC地址1.3 对比理解MAC地址和IP地址1.4 认识MTU1.5 MTU对IP协议的影响1.6 MTU对UDP协议的影响1.7 MTU对于TCP协议的影响1.8 查看硬件地址和MTU 二、ARP协议2.1 ARP协议的作用2.2 ARP协议的工作…

15、Scalable Diffusion Models with Transformers

简介 官网 DiT&#xff08;Diffusuion Transformer&#xff09;将扩散模型的 UNet backbone 换成 Transformer&#xff0c;并且发现通过增加 Transformer 的深度/宽度或增加输入令牌数量&#xff0c;具有较高 Gflops 的 DiT 始终具有较低的 FID&#xff08;~2.27&#xff09;…

springJPA如果利用注解的方式 进行多表关联操作

前言:上一篇我写了个用JPA的Specification这个接口怎么做条件查询并且进行分页的,想学的自己去找一下 地址:springJPA动态分页 今天我们来写个 利用jpa的Query注解实现多表联合查询的demo 注意: 不建议在实际项目中用这玩意. 因为: 1. 用Query写的sql 可读性极差,给后期维护这…

六角螺母缺陷分类数据集:3440张图像

六角螺母缺陷数据集&#xff1a;包含变形&#xff0c;划痕&#xff0c;断裂&#xff0c;生锈&#xff0c;以及优质螺母图片数据&#xff0c;共计3440张&#xff0c;无标注 一.变形螺母-1839 二.断裂螺母-287 三.划痕螺母-473 四.生锈螺母-529 五.优良螺母-312 适用于CV项目&am…

法律行业案例法模型出现,OPenAI公布与法律AI公司Harvey合作案例

Harvey与OpenAl合作&#xff0c;为法律专业人士构建了一个定制训练的案例法模型。该模型是具有复杂推理广泛领域知识以及超越单一模型调用能力的任务的AI系统&#xff0c;如起草法律文件、回答复杂诉讼场景问题以及识别数百份合同之间的重大差异。 Harvey公司由具有反垄断和证…

阿里云服务器199元一年,ECS u1实例性能测评

阿里云服务器ECS u1实例&#xff0c;2核4G&#xff0c;5M固定带宽&#xff0c;80G ESSD Entry盘优惠价格199元一年&#xff0c;性能很不错&#xff0c;CPU采用Intel Xeon Platinum可扩展处理器&#xff0c;购买限制条件为企业客户专享&#xff0c;实名认证信息是企业用户即可&a…

树莓派部署yolov5实现目标检测(ubuntu22.04.3)

最近两天搞了一下树莓派部署yolov5&#xff0c;有点难搞&#xff08;这个东西有点老&#xff0c;版本冲突有些包废弃了等等&#xff09; 最后换到ubuntu系统弄了&#xff0c;下面是我的整体步骤&#xff1a; 1.烧完ubuntu镜像后&#xff0c;接显示器按系统流程进行系统部署(大于…

win10+Intel显卡安装配置stable-diffusion-webui绘画网页

系列文章目录 提示&#xff1a;这里可以添加系列文章的所有文章的目录&#xff0c;目录需要自己手动添加 例如&#xff1a;第一章 Python 机器学习入门之pandas的使用 提示&#xff1a;写完文章后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目…

精准扶贫管理系统|基于Springboot的精准扶贫管理系统设计与实现(源码+数据库+文档)

精准扶贫管理系统目录 目录 基于Springboot的精准扶贫管理系统设计与实现 一、前言 二、系统功能设计 三、系统实现 1、管理员模块的实现 &#xff08;1&#xff09;用户信息管理 &#xff08;2&#xff09;贫困户信息管理 &#xff08;3&#xff09;新闻类型管理 &a…

openGauss学习笔记-256 openGauss性能调优-使用Plan Hint进行调优-优化器GUC参数的Hint

文章目录 openGauss学习笔记-256 openGauss性能调优-使用Plan Hint进行调优-优化器GUC参数的Hint256.1 功能描述256.2 语法格式256.3 参数说明 openGauss学习笔记-256 openGauss性能调优-使用Plan Hint进行调优-优化器GUC参数的Hint 256.1 功能描述 设置本次查询执行内生效的…

程序员沟通之道:TCP与UDP之辩,窥见有效沟通的重要性(day19)

程序员沟通的重要性&#xff1a; 今天被师父骂了一顿&#xff0c;说我不及时回复他&#xff0c;连最起码的有效沟通都做不到怎么当好一个程序员&#xff0c;想想还挺有道理&#xff0c;程序员需要知道用户到底有哪些需求&#xff0c;用户与程序员之间的有效沟通就起到了关键性作…

图DP

目录 有向无环图DP 力扣 329. 矩阵中的最长递增路径 力扣 2192. 有向无环图中一个节点的所有祖先 有向有环图DP 力扣 1306. 跳跃游戏 III 有向无环图DP 力扣 329. 矩阵中的最长递增路径 给定一个 m x n 整数矩阵 matrix &#xff0c;找出其中 最长递增路径 的长度。 对…

Golang | Leetcode Golang题解之第3题无重复字符的最长子串

题目&#xff1a; 题解&#xff1a; func lengthOfLongestSubstring(s string) int {// 哈希集合&#xff0c;记录每个字符是否出现过m : map[byte]int{}n : len(s)// 右指针&#xff0c;初始值为 -1&#xff0c;相当于我们在字符串的左边界的左侧&#xff0c;还没有开始移动r…

50道Java经典面试题总结

1、那么请谈谈 AQS 框架是怎么回事儿&#xff1f; &#xff08;1&#xff09;AQS 是 AbstractQueuedSynchronizer 的缩写&#xff0c;它提供了一个 FIFO 队列&#xff0c;可以看成是一个实现同步锁的核心组件。 AQS 是一个抽象类&#xff0c;主要通过继承的方式来使用&#x…

Linux系统——网络管理

此文章以红帽Linux9版本为例进行讲解。 红帽Linux9版本的网络管理十分全面&#xff0c;可在多处进行网络配置的修改&#xff0c;但需要注意的是&#xff0c;在9版本内&#xff0c;用户可在配置文件内进行网络配置的修改&#xff0c;但系统不会执行修改的命令&#xff0c;而在9之…

C语言中的结构体:高级特性与扩展应用

前言 结构体在C语言中的应用不仅限于基本的定义和使用&#xff0c;还包含一些高级特性和扩展应用&#xff0c;这些特性和应用使得结构体在编程中发挥着更加重要的作用。 一、位字段&#xff08;Bit-fields&#xff09; 在结构体中&#xff0c;我们可以使用位字段来定义成员…