【C++】<知识点> 标准模板库STL(下)

news2024/12/26 0:46:12

文章目录

     六、set与multiset

1. 常用成员函数

2. pair模板

3. set

4. multiset

七、map与multimap

1. map

2. multimap

3. 应用实例

八、容器适配器

1. stack

2. queue

3. priority_queue

九、算法


六、set与multiset

1. 常用成员函数

iterator find(const T& val)查找值为val的元素,返回其迭代器。若未找到,则返回end()

iterator insert(const T& val)

将val插入容器并返回其迭代器。若set类型对象调用insert,返回值类型为pair<迭代器类型名, bool>
void insert(iterator first, iterator last)将区间[first, last)插入容器
int count(const T& val)统计容器内有多少个和val相同的元素
iterator lower_bound(const T& val)查找最大位置的it,使得[begin, it)中所有元素都比val小
iterator upper_bound(const T& val)查找最小位置的it,使得[it, end)中所有元素都比val大
pair<iterator, iterator> equal_range(const T& val)同时求lower_bound和upper_bound
iterator erase(iterator it)删除it指向的元素,返回其后面元素的迭代器(之后不要再用该迭代器++)。另外,erase函数也有重载,可以删除指定元素,还可以删除指定区间。

2. pair模板

/* pair模板内容 */
template <class _T1, class _T2>
struct pair
{
    typedef _T1 first_type;
    typedef _T2 second_type;
    _T1 first;
    _T2 second;

    pair() : first(), second() {}

    pair(const _T1& _a, const _T1& _b) : first(_a), second(_b) {}

    template <class _U1, class _U2>
    pair(const pair<_U1, _U2>& _p) : first(_p.first), second(_p.second) {}
}

/* 第三个构造函数示例:*/
pair<int, int> p(pair<double, double>(5.5, 4.6));
//则p.first = 5, p.second = 4

/* map/multimap容器里放着的都是pair模板类的对象,并按照first从小到大排序 */

3. set

(1) set类模板:

template < class Key, class Pred = less<Key>, class A = allocator<Key> >
class set{...}

//less模板,通过<比较大小,因此自定义类内要重载<
template <class T>
struct less : public binary_function<T, T, bool> {
    bool operator()(const T& x, const T& y) {
        return x < y;
    }
};

(2) 注意:

  • 插入set中已有的元素时,会忽略插入。
  • 当未传入Pred时,默认是按照less从小到大排序。
  • 当传入Pred时,可以按照自定义的排序规则来构建set。
  • 若Key不是基本数据类型,Key类内部要重载运算符<,且形参要写上const否则报错。

(3) 代码示例:

#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include <set>
using namespace std;

class Stu {
private:
	int number;
public:
	Stu() :number(0) {}

	Stu(int a) :number(a) {}

	int getNumber() {
		return this->number;
	}

	friend bool operator<(const Stu& s1, const Stu& s2) {
		return s1.number < s2.number;
	}

	friend ostream& operator<<(ostream& cout, const Stu& s) {
		cout << s.number;
		return cout;
	}

	friend void printStu(const set<Stu>& s) {
		set<Stu>::const_iterator i;
		for (i = s.begin(); i != s.end(); ++i) {
			cout << (*i).number << " ";
		}
		cout << endl;
	}
};

int main()
{
	//创建包含Stu类的set
	set<Stu> s;
	s.insert(Stu(10));
	s.insert(Stu(50));
	s.insert(Stu(4));
	s.insert(Stu(18));
	s.insert(Stu(60));
	printStu(s);//4 10 18 50 60
	//set插入重复元素50,不会插入成功
	typedef set<Stu>::iterator IT;
	pair<IT, bool> ret = s.insert(Stu(50));
	if (ret.second) {
		cout << "插入成功!" << endl;
	}
	else {
		cout << "插入失败!" << endl;
	}
	//同时求取lower_bound和upper_bound
	pair<IT, IT> bounds = s.equal_range(20);
	cout << *bounds.first << " " << *bounds.second << endl;//50 50
	//删除元素60
	s.erase(60);//等价于s.erase(Stu(60));
	printStu(s);//4 10 18 50
	return 0;
}

4. multiset

(1) multiset类模板:

template < class Key, class Pred = less<Key>, class A = allocator<Key> >
class multiset{...}

(2) 注意:

  • multiset允许元素重复,不同于set。
  • multiset插入元素后只是返回iterator。而set插入可能会失败因此返回pair<iterator, bool>。

(3) 代码示例:

#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include <set>
using namespace std;

class Stu {
private:
	int number;
public:
	Stu() :number(0) {}

	Stu(int a) :number(a) {}

	int getNumber() {
		return this->number;
	}

	friend bool operator<(const Stu& s1, const Stu& s2) {
		return s1.number < s2.number;
	}

	friend ostream& operator<<(ostream& cout, const Stu& s) {
		cout << s.number;
		return cout;
	}

	friend void printStu(const multiset<Stu>& s) {
		multiset<Stu>::const_iterator i;
		for (i = s.begin(); i != s.end(); ++i) {
			cout << (*i).number << " ";
		}
		cout << endl;
	}
};

int main()
{
	//创建包含Stu类的set
	multiset<Stu> s;
	s.insert(Stu(10));
	s.insert(Stu(50));
	s.insert(Stu(4));
	s.insert(Stu(18));
	s.insert(Stu(60));
	printStu(s);//4 10 18 50 60
	//set插入重复元素50,会插入成功
	typedef multiset<Stu>::iterator IT;
	IT ret = s.insert(Stu(50));
	if (ret != s.end()) {
		cout << "插入成功!" << endl;
		printStu(s);//4 10 18 50 50 60
	}
	else {
		cout << "插入失败!" << endl;
	}
	//同时求取lower_bound和upper_bound
	pair<IT, IT> bounds = s.equal_range(20);
	cout << *bounds.first << " " << *bounds.second << endl;//50 50
	//删除元素60
	s.erase(60);//等价于s.erase(Stu(60));
	printStu(s);//4 10 18 50 50
	//统计50元素的个数
	cout << s.count(50) << endl;//2
	return 0;
}


七、map与multimap

1. map

(1) map类模板:

template < class Key, class T, class Pred = less<Key>, class A = allocator<Key> >
class map{
    ...
    typedef pair<const Key, T>    value_type;
    ...
}

(2) 注意:

  • map里面存储的对象都是pair类型的,且按照pair的first成员变量(关键字)来排序。
  • map不允许有相同的关键字对象。
  • 创建pair类的对象有三种方式:
    • ①pair<int, double>(1, 5.6);
    • ②map<int, double>::value_type(1, 2.6);
    • ③make_pair(1, 4.6);
  • map实例化的容器对象可以使用"[]"
    • "[key]"返回关键字为key的对象引用(若该对象的关键字不存在,则调用无参构造器创建对象)。
    • "[key] = value"可以修改关键字为key的对象的值为value。

(3) 代码示例:

#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include <map>
using namespace std;

int main()
{
	//创建map对象及添加元素
	typedef map<int, double> mid;
	mid m;
	m.insert(pair<int,double>(15, 2.6));
	m.insert(mid::value_type(26,5.12));//value_type是map内部声明的,等价于pair<int, double>
	m.insert(make_pair(4, -0.25));//make_pair也能创建pair对象
	//迭代器遍历map
	mid::const_iterator p;
	for (p = m.begin(); p != m.end(); ++p) {
		cout << "(" << p->first << ", " << p->second << ") ";
	}
	cout << endl;
	//添加重复key为15的元素,失败
	pair<mid::const_iterator, bool> insert_ret = m.insert(make_pair(15,8.6));
	if (insert_ret.second) {
		cout << "添加成功" << endl;
	}
	else {
		cout << "添加失败" << endl;
	}
	//使用"[key] = value"修改m中关键字为key的值为value
	m[15] = 8.6;
	for (p = m.begin(); p != m.end(); ++p) {
		cout << "(" << p->first << ", " << p->second << ") ";
	}
	cout << endl;
	return 0;
}

2. multimap

(1) multimap类模板:

template < class Key, class T, class Pred = less<Key>, class A = allocator<Key> >
class multimap{
    ...
    typedef pair<const Key, T>    value_type;
    ...
}

(2) 注意:

  • multimap创建的对象与map类似,但是允许有相同关键字对象。
  • multimap实例化的容器对象不能使用"[]"!
  • multimap修改指定关键字的元素的值,只能先用find等函数来确定其迭代器p,然后修改其第二个元素p->second = newValue。

(3) 代码示例:

#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include <map>
using namespace std;

int main()
{
	//创建multimap对象及添加元素
	typedef multimap<int, double> mmid;
	mmid m;
	m.insert(pair<int, double>(90, 6.54));
	m.insert(mmid::value_type(48, -0.652));
	m.insert(make_pair(107, 5.14));
	//迭代器遍历multimap
	mmid::const_iterator p;
	for (p = m.begin(); p != m.end(); ++p) {
		cout << "(" << p->first << ", " << p->second << ") ";
	}
	cout << endl;
	//添加重复元素48,成功
	p = m.insert(make_pair(48, 4.8));
	for (p = m.begin(); p != m.end(); ++p) {
		cout << "(" << p->first << ", " << p->second << ") ";
	}
	cout << endl;
	//统计关键字为48的元素个数
	cout << m.count(48) << endl;
	//查找关键字为90的元素
	p = m.find(90);
	if (p != m.end()) {
		cout << "找到了:";
		cout << "(" << p->first << ", " << p->second << ") " << endl;
	}
	else {
		cout << "未找到" << endl;
	}
	//删除关键字为48的元素
	m.erase(48);
	for (p = m.begin(); p != m.end(); ++p) {
		cout << "(" << p->first << ", " << p->second << ") ";
	}
	cout << endl;
	//修改元素key为107的元素的值为5.2
	mmid::iterator modi = m.find(107);
	if (modi != m.end()) {
		modi->second = 5.2;
	}
	for (p = m.begin(); p != m.end(); ++p) {
		cout << "(" << p->first << ", " << p->second << ") ";
	}
	cout << endl;
	return 0;
}

3. 应用实例

【1】题目来源:MOOC--郭炜老师的C++面向对象设计课程。

【2】题目要求:

【3】分析:

  • 因为需要频繁的进行查找操作,因此使用查找快速的数据结构尤为重要。
  • 由于查询的是score,可以将score作为查询的关键字。同时,题目中规定score可以重复,因此采用multimap。
  • 创建一个类Stu,Stu中存在三种属性:姓名、学号和成绩。将score作为multimap的关键字,将姓名和学号作为multimap的值。因此,在Stu类中将姓名和学号再次打包为一个类。

【4】代码:

#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include <map>
#include <string>
using namespace std;

/* Stu类 */
class Stu {
public:
	class NameID {
	public:
		string name;	//姓名
		int id;			//学号
	};
	//成员变量
	double score;		//成绩
	NameID nameid;		//姓名和学号
};

int main()
{
	//创建multimap容器对象
	multimap<double, Stu::NameID> m;
	//键盘读取数据
	string cmd;
	Stu st;
	while (cin >> cmd) {
		//识别"Add",往m中添加pair对象
		if (cmd == "Add") {
			cin >> st.nameid.name >> st.nameid.id >> st.score;
			m.insert(make_pair(st.score, st.nameid));
			/*for (multimap<double, Stu::NameID>::iterator p = m.begin(); p != m.end(); ++p) {
				cout << p->second.name << " " << p->second.id << " " << p->first << endl;
			}*/
		}
		//识别"Query",查找比指定分数低的最高分获得者信息
		else if (cmd == "Query") {
			double score_tmp;
			cin >> score_tmp;
			multimap<double, Stu::NameID>::iterator ret = m.lower_bound(score_tmp);
			if (ret != m.begin()) {//查找成功,若多个分数相同则打印id最高
				--ret;
				multimap<double, Stu::NameID>::iterator it_max = ret;
				double targetScore = ret->first;
				int id_Max = ret->second.id;
				while (ret->first == targetScore) {
					if (ret->second.id > id_Max) {
						id_Max = ret->second.id;
						it_max = ret;
					}
					if (ret == m.begin()) {
						break;
					}
					else {
						--ret;
					}
				}
				cout << it_max->second.name << " " << it_max->second.id << " " << it_max->first << endl;
			}
			else {//查找失败
				cout << "Nobody" << endl;
			}
		}
		else {
			cout << "命令无效,请重新输入!" << endl;
		}
	}
	return 0;
}


八、容器适配器

1. stack

(1) stack类模板:

template < class T, class Cont = deque<T> >
class stack {
    ...
}

(2) 注意:

  • stack上可以进行push、pop和top操作,针对的都是栈顶元素。
  • stack可以使用vector、list和deque来实现。stack类模板中第二个参数表示用哪种结构来实现,当不传入时默认是deque实现。

(3) 代码示例:

#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include <stack>
using namespace std;

int main()
{
	//创建栈s
	stack<int> s;
	s.push(1);
	s.push(58);
	s.push(34);
	s.push(85);
	//获取栈顶元素
	cout << s.top() << endl;//85
	//弹出栈顶元素
	s.pop();
	cout << s.top() << endl;//34
	return 0;
}

2. queue

(1) queue类模板:

template < class T, class Cont = deque<T> >
class queue {
    ...
}

(2) 注意:

  • queue可以使用list和deque实现,默认是deque实现。
  • queue也有pop、push和front操作,但是pop和front操作都针对队头,push针对队尾。
  • back成员函数可以返回队尾元素的引用。

(3) 代码示例:

#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include <queue>
using namespace std;

int main()
{
	//创建单向队列q
	queue<int> q;
	q.push(15);
	q.push(520);
	q.push(1314);
	q.push(666);
	//弹出所有元素,并输出
	while (!q.empty()) {
		cout << q.front() << endl;
		q.pop();
	}
	return 0;
}

3. priority_queue

(1) priority_queue类模板:

template < class T, class Cont = vector<T>, class Compare = less<T> >
class priority_queue {
    ...
}

(2) 注意:

  • priority_queue可以使用vector和deque实现,默认使用vector实现。
  • priority_queue底层使用堆排序,保证最大元素总是位于队头。
  • priority_queue中,push和pop的时间复杂度都是O(log n)。top的时间复杂度为O(1)。
  • 针对总是要获取最大值或最小值的情况,可以考虑使用priority_queue。

(3) 代码示例:

#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include <queue>
using namespace std;
int main()
{
	//创建优先级队列,将最小的元素放置于队头
	priority_queue<int, vector<int>, greater<int>> pq;
	pq.push(89);
	pq.push(55);
	pq.push(4);
	pq.push(108);
	//弹出队头,并输出
	while (!pq.empty()) {
		cout << pq.top() << endl;
		pq.pop();
	}
	return 0;
}


九、算法

由于头文件<algorithm>中包含太多函数,并且许多函数不常用,因此这里转载其他兄弟归纳的算法函数,见C++ algorithm函数简介(详细)-CSDN博客。用到哪个函数再去查怎么调用即可。

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

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

相关文章

(C11) 泛型表达式

文章目录 ⭐语法⭐举例&#x1f6a9;判断对象类型&#x1f6a9;判断指针&#x1f6a9;函数重载&#x1f6a9;嵌套使用 END ⭐语法 Ref: 泛型选择 (C11 起) - cppreference.com 关键词&#xff1a; Genericdefault _Generic(控制表达式 , 关联列表) (C11 起) 关联列表 类型名:…

SQLI-labs-第二十三关

第二十三关 目录 第二十三关 1、判断注入点 2、判断数据库 3、判断表名 4、判断字段名 5、获取数据库的信息 6、使用group_concat() 和concat_ws() 知识点&#xff1a;注释符过滤绕过 思路&#xff1a; 分析源码可知&#xff0c;使用了preg_replace()函数过滤了注释符…

计算机图形学入门01:概述

1.什么是图形学? The use of computers to synthesize and manipulate visual information. 图形学是合成和操纵视觉信息的计算机应用。 百度百科&#xff1a;计算机图形学(Computer Graphics&#xff0c;简称CG)是一种使用数学算法将二维或三维图形转化为计算机显示器的栅格…

2024年统计、数据分析与大数据技术国际会议(SDBT 2024)

2024年统计、数据分析与大数据技术国际会议&#xff08;SDBT 2024&#xff09; 2024 International Conference on Statistics, Data Analysis, and Big Data Technology 【重要信息】 大会地点&#xff1a;广州 大会时间&#xff1a;2024年7月22日 大会官网&#xff1a;http…

鸿蒙开发接口UI界面:【@ohos.router (页面路由)】

页面路由 说明开发前请熟悉鸿蒙开发指导文档&#xff1a;gitee.com/li-shizhen-skin/harmony-os/blob/master/README.md点击或者复制转到。 本模块首批接口从API version 8开始支持。后续版本的新增接口&#xff0c;采用上角标单独标记接口的起始版本。页面路由需要在页面渲染完…

VUE3+TS+elementplus+Django+MySQL实现从数据库读取数据,显示在前端界面上

一、前言 前面通过VUE3和elementplus创建了一个table&#xff0c;VUE3TSelementplus创建table&#xff0c;纯前端的table&#xff0c;以及使用VUE3TSelementplus创建一个增加按钮&#xff0c;使用前端的静态数据&#xff0c;显示在表格中。今天通过从后端获取数据来显示在表格…

Keras深度学习框架第二十四讲:KerasNLP概述

1、KerasNLP简介 KerasNLP是一个与TensorFlow深度集成的库&#xff0c;旨在简化NLP&#xff08;自然语言处理&#xff09;任务的建模过程。它提供了一系列高级API&#xff0c;用于预处理文本数据、构建序列模型和执行常见的NLP任务&#xff0c;如情感分析、命名实体识别和机器…

PgMP:项目集管理,哪些人适合学习?

美国项目管理协会&#xff08;PMI&#xff09;对项目集经理&#xff08;Program Manager&#xff09;的角色做出如下的定义&#xff1a; 在最少的领导/监督下&#xff0c;项目集经理PgMP负责在商业和组织目的下协调管理多个相关项目。这些项目含有跨部门、组织、地理区域…

C 基础环境配置(vscode || vs)

目录 一.发展 二. 环境设置 1.vs2022 2.vscode (1.)首先下载VsCode (2)安装vsCode插件 (3)下载MinGW-W64 (4)配置文件 (5)注意把里面配置的:mingw64路径改为自己的路径 (6)示例代码 三.总结 一.发展 编程语言的发展 机器语言(打孔纸带编程),汇编语言,高级语言,一步步…

猫耳 WebSocket 跨端优化实践

前言 在现代的移动应用程序中&#xff0c;长连接是一种不可或缺的能力&#xff0c;包括但不限于推送、实时通信、信令控制等常见场景。在猫耳FM的直播业务中&#xff0c;我们同样使用了 WebSocket 长连接作为我们实时通信的基础。 在我们推进用户体验优化的工作中&#xff0c;…

利用AI办公工具类API,大幅提高办公效率

AI办公工具类API是一项革命性的技术&#xff0c;利用人工智能的力量为办公场景提供了许多创新的解决方案。借助AI办公工具类API&#xff0c;用户可以实现自动化的文档处理、语音转文字、图像识别、数据分析等多种功能&#xff0c;大大提高了办公效率和工作质量。此外&#xff0…

LiveGBS流媒体平台GB/T28181用户手册-国标级联:添加上级平台、选择通道、推送通道级联会话、搜索、删除

LiveGBS流媒体平台GB/T28181用户手册-国标级联:添加上级平台、选择通道、推送通道级联会话、搜索、删除 1、国标级联1.1、添加上级平台1.2、注册状态1.3、选择通道1.4、推送通道1.5、级联会话1.6、搜索1.7、删除 2、搭建GB28181视频直播平台 1、国标级联 1.1、添加上级平台 点…

【golang学习之旅】go mod tidy

系列文章 【golang学习之旅】报错&#xff1a;a declared but not used 【golang学习之旅】Go 的基本数据类型 【golang学习之旅】深入理解字符串string数据类型 目录 系列文章go mod tidy的作用 go mod tidy的作用 把项目所依赖的包添加到go.mod文件中去掉go.mod文件中项目不…

使用 RT 矩阵进行 3D 点云变换详解(基于 PCL 和 Eigen 库)

在 3D 点云处理中&#xff0c;RT 矩阵是一个常用的工具&#xff0c;用于对点云进行旋转和平移操作。本文将详细介绍 RT 矩阵的概念&#xff0c;并通过一个示例程序演示如何基于 PCL 和 Eigen 库将一帧点云进行矩阵变换再输出。 本教程的示例代码和点云数据可在 GitHub 下载。 什…

告别裸奔,聊聊主流消息队列的认证和鉴权!

大家好&#xff0c;我是君哥。 我们在使用消息队列时&#xff0c;经常关注的是消息队列收发消息的功能。但好多时候需要对客户端有一定的限制&#xff0c;比如只有持有令牌的客户端才能访问集权&#xff0c;不允许 Producer 发送消息到某一个 Topic&#xff0c;或者某一个 Top…

网工必备的几种远程工具,教你使用

号主&#xff1a;老杨丨11年资深网络工程师&#xff0c;更多网工提升干货&#xff0c;请关注公众号&#xff1a;网络工程师俱乐部 下午好&#xff0c;我的网工朋友。 干网工这行&#xff0c;工具是必备的&#xff0c;不会用工具赋能工作的网工不是好网工&#xff01; 拥有一套…

Matplotlib 实践指南:图形样式、风格与标记探索

目录 前言 第一点&#xff1a;导入模块 第二点&#xff1a;创建二维图 第三点&#xff1a;创建统计图 总结 前言 Matplotlib 是一个强大的数据可视化库&#xff0c;可用于创建各种类型的图形。在本文中&#xff0c;我们将研究如何在 Matplotlib 中设置图形的颜色、风格和标记…

深入了解Nginx(一):Nginx核心原理

一、Nginx核心原理 本节为大家介绍Nginx的核心原理,包含Reactor模型、Nginx的模块化设计、Nginx的请求处理阶段. &#xff08;本文源自微博客,且已获得授权&#xff09; 1.1、Reactor模型 Nginx对高并发IO的处理使用了Reactor事件驱动模型。Reactor模型的基本组件包含时间收集…

redis数据类型set,zset

华子目录 Set结构图相关命令sdiff key1 [key2]sdiffstore destination key1 [key2...]sinter key1 [key2...]sinterstore destination key1 [key2...]sunion key1 [key2...]sunionstore destination key1 [key2...]smove source destination memberspop key [count]sscan key c…

51驱动DY-SV20F语音播放模块

51驱动DY-SV20F语音播放模块 简介模块特征电气参数工作模式配置原理图代码结果图 简介 DY-SV20F 是一款一对一分段触发控制播放器&#xff0c;支持 MP3,WAV 解码格式&#xff1b; 可分段触发 9 首曲目&#xff1b;低电平触发&#xff1b;3.7-5VDC 宽电压供电&#xff0c;直驱 …