常用STL容器(c++)

devtools/2024/10/18 19:28:17/

目录

一、vector容器---动态数组

1.为什么要引进动态数组?

2.引用库

3.构造一个动态数组

4.一些增删查改动态数组的方法

5.使用基础的vector

6.构造函数

7.二维动态数组

二、set()容器---集合

1.构造一个集合

2.方法

2.1插入元素

2.2判断元素是否存在

2.3迭代器

2.4清空

2.5基本应用

3.运算符重载

4.用set来存储一个二维坐标系上的点的集合---关于结构体

 三、map()容器---映射

1.构造一个映射

2.基本应用

3.map套set

4.map套用map

四、锯齿矩阵


一、vector容器---动态数组

1.为什么要引进动态数组?

(1)有些时候想开一个数组,单数却不知道应该开多大长度的数组合适,因为我们需要用到的数组可能会根据情况变动。这时候我们就需要用到动态数组。

(2)c++中的动态数组写作vector

2.引用库

c++中vector的实现在一个<vector>头文件中,在代码开头引入这个头文件,并在引入所有头文件之后加上一句using namespace std

#include<vector>
using namespace std;
int main(void)
{return 0;
}

3.构造一个动态数组

vector<T> vec  其中T是我们数组要存储的数据类型:int  float  double都可以

4.一些增删查改动态数组的方法

vector方法总结:
push_back:在末尾加入一个元素
pop_back:删除动态数组的最后一个元素
size:获取长度
clear:清空 但是只是清空vector,并不会清空开的内存。用一种方法可以清空内存:

//vector<int> v;

vector<int>().swap(v);

5.使用基础的vector

#include<iostream>
#include<vector>
using namespace std;
int main(void)
{vector<int> v;for (int i = 1;i <= 10; i++){v.push_back(i * i);}for (int i = 0; i < v.size(); i++){cout << v[i] << " ";}cout << endl;return 0;
}

6.构造函数

引言:我们都知道通过push_back()来向动态数组添加一个元素。如果我们需要一个长度为n的,全是1的动态数组,用for循环来写就小题大作了。so我们可以通过一个构造函数快速构建这样的一个动态数组。所谓构造函数,就是我们在定义一个对象的时候就可以给它赋值

#include<iostream>
#include<vector>
using namespace std;
int main(void)
{int n = 10;vector<int> vec(n, 1);//构造函数,第一个参数是初始的动态数组的长度,第二个参数表示初始的数组里面每个元素的值。//如果不传入第二个参数,那么初始的值都是0//通过合理的使用构造函数,可以减少代码量for (int i = 0; i < n; i++){cout << vec[i] << " ";}return 0;
}

7.二维动态数组

vector<vector<int> >vec2 这样定义了一个二维动态数组  注意:<int> >中间有一个空格,这个空格一定要加上,否则这些老版本的编译器不能通过编译

#include<iostream>
#include<vector>
using namespace std;
int main(void)
{int n = 5;vector<vector<int> > vec2;for (int i = 0; i < n; i++){vector<int> x(i + 1, 1);vec2.push_back(x);}for (int i = 0; i < 5; i++){for (int j = 0; j < vec2[i].size(); j++){cout << vec2[i][j] << " ";}cout << endl;}return 0;
}

二维动态数组的每一维的长度都可以不一样,可以是任意形状的。借助构造函数,我们可以快速构造一个n行m列的动态数组,每个元素的初始值是0:

vector<vector<int> > vec2(n,vector<int>(m,0));

下面我们用二维动态数组来记录一个1到5的乘法表

#include<iostream>
#include<vector>
using namespace std;
int main(void)
{vector<vector<int> > vec2;for (int i = 0; i < 5; i++){vec2.push_back(vector<int>());}for (int i = 0; i < 5; i++){for (int j = 0; j <= i; j++){vec2[i].push_back((i + 1) * (j + 1));}}for (int i = 0; i < vec2.size(); i++){for (int j = 0; j <= i; j++){cout <<j+1<<"*"<<i+1<<"="<< vec2[i][j] << "\t";}cout << endl;}return 0;
}

二、set()容器---集合

1.构造一个集合

c++中直接构造一个set的语句为:set<T> s . 这样我们定义了一个名为s的、储存T类型数据的集合,其中T是集合要储存的数据类型。初始的时候s是空集合。比如

set<int> aa,set<string> bbb等等

2.方法

2.1插入元素

c++中用insert()函数向集合中插入一个新的元素。注意如果集合中已经存在了某个元素,再次插入不会产生任何效果,集合中是不会出现重复元素的。

2.2判断元素是否存在

c++中如果你想知道某个元素是否在集合中出现,你可以直接用count()函数。如果集合中存在我们要查找的元素,返回1,否则返回0。

2.3迭代器

.遍历元素:
c++通过迭代器可以访问集合中的每个元素,迭代器就好像一根手指指向set中的某个元素。通过操作这个手指,我们可以改变它指向的元素
通过*(解引用运算符,不是乘号的意思)操作可以获取迭代器指向的元素。
set<T>::iterator it就定义了一个迭代器it 注意:begin函数返回容器的其实元素的迭代器,end函数返回容器的尾后迭代器

2.4清空

c++中调用clear()函数就可清空set,同时会清空set占用的内存

2.5基本应用

#include<set>
#include<iostream>
using namespace std;
int main(void)
{set<string> country;country.insert("China");country.insert("American");country.insert("France");set<string>::iterator it;for (it = country.begin(); it != country.end(); it++){cout << *it << endl;}cout << endl;country.erase("American");//erase()函数用于删除集合中的元素country.erase("England");for (it = country.begin(); it != country.end(); it++){cout << *it << endl;}cout << endl;if (country.count("China")){cout << "China in set" << endl;}country.clear();return 0;
}

3.运算符重载

运算符重载:
set经常会配合结构体来使用,用set来存储结构体和vector有些区别,正如我们前面所说的那样,set是需要经过排序的,系统自带的数据类型有默认的比较大小的规则,而我们自定义的结构体,系统是不可能知道这个结构体比较大小的方式的
所以我们需要一种方式来告诉系统怎样比较这个结构体的大小。其中一种方法叫做运算符重载,我们需要重新定义小于符号。

struct Node
{int x, y;bool operator<(const Node& rhs) const{if (x == rhs.x){return y < rhs.y;}else{return x < rhs.x;}}
};

4.用set来存储一个二维坐标系上的点的集合---关于结构体

#include<iostream>
#include<set>
using namespace std;
struct Point
{int x, y;bool operator<(const Point& rhs)const{if (x == rhs.x){return y < rhs.y;}else{return x < rhs.x;}}
};
int main(void)
{int n;set<Point> v;cin >> n;for (int i = 0; i < n; i++){Point temp;cin >> temp.x >> temp.y;v.insert(temp);}for (set<Point>::iterator it = v.begin(); it != v.end(); it++){cout << it->x << " " << it->y << endl;}return 0;
}

 三、map()容器---映射

映射:是指两个集合之间的元素的相互对应关系。通俗的说,就是一个元素对应另外一个元素。比如有一个姓名的集合{“tom”,“jone”},班级集合{1,2}。姓名与班级之间可以有如下的映射关系:
class{"tom"}=1,class{"jone"}=2,class{"Mary"}=1;
我们称其中的姓名集合为关键字集合(key),班级集合为值集合(value)
c++中我们常用的映射是map

1.构造一个映射

在c++中,我们构造一个map的语句为:map<T1,T2> m。这样我们定义了一个名为m的从T1类型到T2类型的映射。初始的时候m是空映射。比如map<string,int> m构建一个字符串到整数的映射,这样我们可以把一个字符串和一个整数关联起来

2.基本应用

#include<map>
#include<iostream>
using namespace std;
int main(void)
{map<string, int> dict;dict["Tom"] = 1;dict["Jone"] = 2;dict["Mary"] = 1;if (dict.count("Mary")){cout << "Mary is class " << dict["Mary"] << endl;;dict["Mary"] = 5;}for (map<string, int>::iterator it = dict.begin(); it != dict.end(); it++){cout << it->first << " is in class " << it->second << endl;}return 0;
}

3.map套set

(1)map套用set:为了帮助理解,我们举一个生活中实际例子。全校有很多班级,每个班级每个人都会有中文名。现在我们需要用一种方式来记录全校的同学的名字。如果直接用一个set记录,对于重名的同学,那么就没办法分辨了
我们可以把全校的班级进行编号,对每个班级建立一个set,也就是每个班级都映射成一个set,这样就能分辨不同班级的同名同学了
用法:map<int,set<string> > s就定义上面描述的数据结构,和二维的vector一样,两个> >中间的空格不能少
这样我们就可以进行插入和查询了,比如对2班的yuhaoran同学,我们s[2].insert("yuhaoran").然后查询yuhaoran是不是一个2班的人,是s[2].count("yuhaoran").然后还可以把他从二班删除,s[2].erase("yuhaoran")

4.map套用map

上面的结构没有办法解决同伴同名的情况。实际上,如果同班同名,单单通过名字本身是无法分辨的,需要通过其他特征来分辨。所以为了简单起见,我们只需要记录每个班级同名的人的个数
map<int,map<string,n> > s。2班有一个yuhaoran,s[2]["yuhaoran"]++ 。2班又转来了一个yuhaoran,s[2]["yuhaoran"]++
现在2班一共有多少个yuhaoran? cout<<s[2]["yuhaoran"]<<endl;

#include<iostream>
#include<map>
#include<string>
using namespace std;
int main(void)
{map<int, map<string, int> > info;int n;cin >> n;for (int i = 0; i < n; i++){int class_id;string name;cin >> class_id >> name;info[class_id][name]++;}for (map<int, map<string, int> >::iterator it = info.begin(); it != info.end(); it++){for (map<string, int>::iterator it1 = it->second.begin(); it1 != it->second.end(); it1++){cout << "There are " << it1->second << " people name " << it1->first << " int class " << it->first << endl;}}return 0;
}

四、锯齿矩阵

是指每行包含的元素个数不相同的矩阵

#include<iostream>
#include<vector>
using namespace std;
vector<int> mat[10005];//定义了一个vector类型的数组
int main(void)
{int n, m,x,y;cin >> n >> m;for (int i = 0; i < m; i++){cin >> x >> y;mat[x].push_back(y);}for (int i = 0; i <= n; i++){for (int j = 0; j < mat[i].size(); j++){if (j != mat[i].size() - 1){cout << mat[i][j] << " ";}else{cout << mat[i][j] << endl;}}cout << endl;}return 0;
}


http://www.ppmy.cn/devtools/125130.html

相关文章

【最新华为OD机试E卷-支持在线评测】跳房子I(100分)多语言题解-(Python/C/JavaScript/Java/Cpp)

🍭 大家好这里是春秋招笔试突围 ,一枚热爱算法的程序员 💻 ACM金牌🏅️团队 | 大厂实习经历 | 多年算法竞赛经历 ✨ 本系列打算持续跟新华为OD-E/D卷的多语言AC题解 🧩 大部分包含 Python / C / Javascript / Java / Cpp 多语言代码 👏 感谢大家的订阅➕ 和 喜欢�…

Python 网络爬虫:从入门到实践

在大数据时代&#xff0c;网络爬虫&#xff08;Web Scraping&#xff09;是一项重要的技术&#xff0c;能帮助我们从互联网上获取大量的信息。Python 以其简洁的语法和丰富的库支持&#xff0c;成为实现网络爬虫的首选语言。本文将详细介绍Python网络爬虫的基础知识、常用库&am…

Java对接支付宝支付接口

在Java中对接支付宝支付接口&#xff0c;通常需要使用支付宝提供的开放平台API。以下是一个基本的步骤指南&#xff0c;帮助你开始&#xff1a; 1. 注册支付宝开发者账号 首先&#xff0c;你需要在支付宝开放平台注册一个开发者账号。注册完成后&#xff0c;你需要创建一个应…

使用 Cesium 实现气象可视化的详细教程

Cesium 是一个基于 WebGL 的开源 JavaScript 库&#xff0c;常用于构建三维地球和地图应用。通过结合 Cesium 与气象数据&#xff0c;我们可以实现逼真的气象可视化效果&#xff0c;例如展示温度场、降雨量、风速等气象现象。本文将详细介绍如何使用 Cesium 实现气象数据的可视…

MyBatis 基础操作

新建springboot项目&#xff0c;添加Lombok&#xff0c;Mybatis&#xff0c;MySQL的依赖项。 application.properties中引入数据库连接信息。 #驱动类名称 spring.datasource.driver-class-namecom.mysql.cj.jdbc.Driver #数据库连接的url spring.datasource.urljdbc:mysql://…

4.stm32 GPIO输入

按键简介 按键&#xff1a;常见的输入设备&#xff0c;按下导通&#xff0c;松手断开 按键抖动&#xff1a;由于按键内部使用的是机械式弹簧片来进行通断的&#xff0c;所以在按下和松手的瞬间会伴随有一连串的抖动 传感器模块简介 传感器模块&#xff1a;传感器元件&#…

您是否也在寻找免费的 PDF 编辑器工具?10个备选PDF 编辑器工具

您是否也在寻找免费的 PDF 编辑器工具&#xff1f; 如果是&#xff0c;那么您在互联网上处于最佳位置&#xff01; 本指南中提到的所有 10 大免费 PDF 编辑器工具都易于使用&#xff0c;可以允许您添加文本、更改图像、添加图形、填写表格、添加签名等等。 因此&#xff0c;…

Maven 入门详解

在 Java 世界中&#xff0c;项目依赖管理就像是一张错综复杂的网&#xff0c;稍有不慎就会陷入 “依赖地狱”。而 Maven&#xff0c;就像一位经验丰富的"项目经理"&#xff0c;为我们提供了一套标准化的项目管理方案&#xff0c;将混乱的依赖关系梳理得井井有条。 1.…