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

文章目录

     六、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博客。用到哪个函数再去查怎么调用即可。

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

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

相关文章

Kubernetes和Docker对不同OS和CPU架构的适配关系

Docker Docker官网对操作系统和CPU架构的适配关系图 对于其他发行版本&#xff0c;Docker官方表示没有测试或验证在相应衍生发行版本上的安装&#xff0c;并建议针对例如Debian、Ubuntu等衍生发行版本上使用官方的对应版本。 Kubernetes X86-64 ARM64 Debian系 √ √ Re…

鸿蒙学习第一课--认识目录结构

项目结构介绍 module.json5 src > main > module.json5&#xff1a;Stage模型模块配置文件。主要包含HAP包的配置信息、应用/服务在具体设备上的配置信息以及应用/服务的全局配置信息。具体的配置文件说明&#xff0c;详见module.json5配置文件。 资源分类和访问 关于s…

【C++题解】1133. 字符串的反码

问题&#xff1a;1133. 字符串的反码 类型&#xff1a;字符串 题目描述&#xff1a; 一个二进制数&#xff0c;将其每一位取反&#xff0c;称之为这个数的反码。下面我们定义一个字符的反码。 如果这是一个小写字符&#xff0c;则它和字符 a 的距离与它的反码和字符 z 的距离…

《当微服务遇上Ribbon:一场负载均衡的华丽舞会》

在微服务的厨房里&#xff0c;如何确保每一道服务都恰到好处&#xff1f;揭秘Spring Cloud Ribbon如何像大厨一样精心调配资源&#xff0c;让负载均衡变得像烹饪艺术一样简单&#xff01; 文章目录 Spring Cloud Ribbon 详解1. 引言微服务架构中的负载均衡需求Spring Cloud Rib…

SwiftUI中AppStorage的介绍使用

在Swift中&#xff0c;AppStorage是SwiftUI中引入的一个属性包装器&#xff0c;在这之前我们要存储一些轻量级的数据采用UserDefaults进行存取。而AppStorage用于从UserDefaults中读取值&#xff0c;当值改变时&#xff0c;它会自动重新调用视图的body属性。也就是说&#xff0…

地图数据导入

OpenStreetMap 地图数据官网 Geofabrik Download Server 下载数据 china-latest-free.shp.zip 解压到 D:\works\mapworks\shp\tmp 解压找到相关数据&#xff08;目前我要的是铁路数据&#xff09; 导入 gis_osm_railways_free_1.shp 到 pgAdmin4 数据库 1.启动 C:\Progra…

unity制作app(9)--拍照 相册 上传照片

1.传输照片&#xff08;任何较大的数据&#xff09;都需要扩展服务器的内存空间。 2.还需要base64编码 2.1客户端发送位置的编码 2.2服务器接收部分的代码

“2024 亚马逊云科技中国峰会,挑战俱乐部 Hands On 动手实验课程正在直播中,点击链接畅享生成式AI建构之旅,赢心动好礼

只看不过瘾&#xff1f;别急&#xff01;我们为您准备了【生成式AI助手 Amazon Q 初体验】动手实验&#xff0c;一款生成式人工智能 (AI) 支持的对话助理&#xff0c;可以帮助您理解、构建、扩展和操作 Amazon 应用程序&#xff0c;您可以询问有关 Amazon 架构、最佳实践、文档…

K8S集群监控方案之Prometheus+kube-state-metrics+Grafana

序言 | Prometheus 中文文档 方案简单架构图 一、部署kube-state-metrics 1、部署文件下载 地址 kube-state-metrics/examples/standard at main kubernetes/kube-state-metrics GitHub 2、修改下载的文件 2.1、修改镜像 原镜像可能下载不了&#xff0c;这里修改deploy…

R实验 参数估计

实验目的&#xff1a; 掌握矩法估计与极大似然估计的求法&#xff1b;了解估计量的优良性准则&#xff1a;无偏性、有效性、相合性&#xff08;一致性&#xff09;&#xff1b;学会利用R软件完成一个正态总体均值和两个正态总体均值差的区间估计&#xff1b;学会利用R软件完成…

预训练模型语义相似性计算(十一) - M3E和BGE

M3E m3e由MokaAI 训练&#xff0c;开源和评测。 m3e的详细介绍可以看官方的github介绍。本文简要摘录其中一些点&#xff0c;以便后续的应用。 1.千万级 (2200w) 的中文句对数据(开源)。 2.支持同质相似句计算(s2s)和异质检索(s2p)&#xff0c;后续支持代码检索。 3.m3e基座模…

Android数据缓存框架 - 内存数据载体从LiveData到StateFlow

引言&#xff1a;所有成功者的背后&#xff0c;都有一份艰苦的历程&#xff0c;不要只看到了人前的风光&#xff0c;而低估了他们背后所付出的努力。 随着flow到流行度越来越高&#xff0c;有开发者呼吁我使用flow&#xff0c;于是我就如你们所愿&#xff0c;新增了StateFlow作…

专家解读 | NIST网络安全框架(2):核心功能

NIST CSF是一个关键的网络安全指南&#xff0c;不仅适用于组织内部&#xff0c;还可帮助管理第三方网络安全风险。CSF核心包含了六个关键功能——治理、识别、保护、检测、响应和恢复&#xff0c;以及与这些功能相关的类别和子类别。本文将深入探讨CSF核心的主要内容&#xff0…

7个靠谱的副业赚钱方法,宝妈,上班族,学生党可以做的兼职副业

你是否也曾面临过这样的困境&#xff1a;生活费紧张&#xff0c;想要找份兼职来补贴家用或是满足自己的小心愿&#xff1f;别担心&#xff0c;今天我将带领你踏入这个丰富多彩的兼职世界&#xff0c;助你轻松达成月入过千的小目标&#xff01; 在我漫长的兼职探索旅程中&#…

js的学习

什么是JavaScript? JavaScript(简称:JS)是一门跨平台、面向对象的脚本语言。是用来控制网页行为的&#xff0c;”它能使网页可交互。 JavaScript 和Java 是完全不同的语言&#xff0c;不论是概念还是设计。但是基础语法类似。 JavaScript在1995 年由 Brendan Eich 发明&#x…

初学者必读:Midjourney AI创作工具的简易使用手册!

在数字化时代&#xff0c;AI的应用不断推动着各个领域的发展。在这些领域中&#xff0c;AI在艺术和设计方面的应用引起了广泛的关注。AI绘画软件作为今年的热门&#xff0c;Midjourney 通过其独特的原理和方便的使用方法&#xff0c;为创作者提供了一个全新的创作逼真绘画的平台…

设计模式15——享元模式

写文章的初心主要是用来帮助自己快速的回忆这个模式该怎么用&#xff0c;主要是下面的UML图可以起到大作用&#xff0c;在你学习过一遍以后可能会遗忘&#xff0c;忘记了不要紧&#xff0c;只要看一眼UML图就能想起来了。同时也请大家多多指教。 享元模式&#xff08;Flyweigh…

Golang协程和通道

文章目录 协程&#xff08;goroutine&#xff09;基本介绍GMP模型协程间共享变量 通道&#xff08;channel&#xff09;基本介绍channel的定义方式channel的读写channel的关闭channel的遍历方式只读/只写channelchannel最佳案例select语句 协程&#xff08;goroutine&#xff0…

力扣62 不同路径 Java版本

文章目录 题目描述代码 题目描述 一个机器人位于一个 m x n 网格的左上角 &#xff08;起始点在下图中标记为 “Start” &#xff09;。 机器人每次只能向下或者向右移动一步。机器人试图达到网格的右下角&#xff08;在下图中标记为 “Finish” &#xff09;。 问总共有多少…

就说说Java初学者求职准备项目的正确方式

当下不少Java初学者也知道求职时项目的重要程度&#xff0c;但在简历上写项目和准备面试项目时&#xff0c;真有可能走弯路&#xff0c;这样的话&#xff0c;加重学习负担还是小事&#xff0c;还真有可能导致无法入职。 1 对于在校生和应届生来说&#xff0c;你去跑通个学习项…