C++STL库之map

news2024/12/26 0:09:27

文章目录

  • 关于仿函数
  • stack
  • deque(双端对列)
  • queue
  • priority_queue
  • map(重点)
  • set(去重)

关于仿函数

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

//C++不能重载的运算符sizeof、 ::、 ? :、 .、 *、
class Add
{
public:
	int operator()(int a, int b)const
	{
		return a + b;
	}
};
//函数对象,仿函数,函子
int main()
{
	Add add;

	int x = 10, y = 20, z = 30; 
	z = add(x, y);  //C++11
	z = add.operator()(x, y);  //重载了括号调用

	cout << z << endl;
}
template<class _Ty>
class Add
{
public:
	_Ty operator()(const _Ty& a, const _Ty& b)const
	{
		return a + b;
	}
};

int main()
{
	Add<int>iadd;
	Add<double>dadd;

	int x = 10, y = 20, z = 0;
	z = Add<int>()(x, y);   //Add<int>():类型名+()  创建了不具名对象(右值)
	z = Add<int>().operator()(x, y);  //仿函数
	return 0;
}
int main()
{
	std::vector<int>ar = { 1,4,5,6,7,8,3,2,9,0 };
	std::sort(ar.begin(),ar.end(),std::less<int>());
	for (auto& x : ar)
	{
		cout << x << " ";
	}
	cout << endl;

	std::sort(ar.begin(), ar.end(), std::greater<int>()); //仿函数,从大到小排序

	for (auto& x : ar)
	{
		cout << x << " ";
	}
	cout << endl;
}
struct my_less
{
	bool operator()(const _Ty& a, const _Ty& b)const
	{
		return a < b;
	}
};
template<class _Ty>
struct my_greater
{
	bool operator()(const _Ty& a, const _Ty& b)const
	{
		return a > b;
	}
};

template<class _BI,class _Fn>
void my_sort(_BI _first, _BI _last,_Fn fn)
{
	cout << typeid(_BI).name() << endl;
	cout << typeid(_Fn).name()<< endl;
	for (_BI i = _first;i != _last; ++i)  //插入排序
	{
		_BI k = i;
		for (_BI j = i+1; j!=_last; ++j)
		{
			if (*k > *j)
			{
				k = j;
			}
		}
		if (k!= i)
		{
			std::swap(*k, *i);
		}
	}
}

int main()
{
	std::vector<int>ar = { 1,4,5,6,7,8,3,2,9,0 };
	my_sort(ar.begin(), ar.end(),my_less<int>());
	//std::sort(ar.begin(),ar.end(),std::less<int>());
	for (auto& x : ar)
	{
		cout << x << " ";
	}
	cout << endl;

	my_sort(ar.begin(), ar.end(),my_greater<int>()); //仿函数,从大到小排序

	for (auto& x : ar)
	{
		cout << x << " ";
	}
	cout << endl;
}

运行结果:
在这里插入图片描述

stack

  • 关于栈的返回值:以引用形式返回,以值的形式接受(不能以引用接受,会产生失效引用,或者会修改栈顶的值)
  • 默认情况栈的底层实现,双端对列实现
class PtrInt
{
	int* ptr;
public:
	PtrInt(int x = 0) :ptr(new int(x))
	{
		cout << "Create PtrInt:" << endl;
	}
	PtrInt(const PtrInt& pt) :ptr(new int())
	{
		if (pt.ptr != nullptr)
		{
			*ptr = *pt.ptr;
		}
		cout << "Copy Create:" << endl;
	}
	PtrInt& operator=(const PtrInt& pt)
	{
		if (this != &pt)
		{
			delete ptr;
			ptr = new int();
			if (pt.ptr != nullptr)
			{
				*ptr = *pt.ptr;
			}
			cout << "operator=()" << endl;
		}
		return *this;
	}
	PtrInt(PtrInt&& pt) :ptr(pt.ptr)
	{
		pt.ptr = nullptr;
		cout << "move create" << endl;
	}
	PtrInt& operator=(PtrInt&& pt)
	{
		if (this != &pt)
		{
			delete ptr;
			ptr = pt.ptr;
			pt.ptr = nullptr;
		}
		cout << "move operator=()" << endl;
		return *this;
	}
	~PtrInt()
	{
		delete ptr;
		ptr = nullptr;
		cout << "Destory PtrInt" << endl;
	}
	
	void SetValue(int x)
	{
		if (ptr != nullptr)
		{
			*ptr = x;
		}
		else
		{
			ptr = new int(x);
		}
	}
	int GetValue()const
	{
		if (ptr != nullptr)
		{
			return *ptr;
		}
		else
		{
			return -1;
		}
	}
	void Print()const
	{
		if (ptr != nullptr)
		{
			cout << *ptr << endl;
		}
	}
};

int main()
{
	stack<PtrInt>ist;
	ist.push(PtrInt(10));
	ist.push(PtrInt(20));
	ist.push(PtrInt(30));

	stack<PtrInt, std::list<PtrInt>>list; //链栈
	stack<PtrInt, std::vector<PtrInt>>sqst; //顺序栈

	PtrInt &val = ist.top(); //返回值为引用,但是以引用接受,最好以值接受,以引用返回
	//为什么以引用的形式返回,因为以值返回会产生将亡值对象
	
	val.Print();
	ist.pop();
	//val.Print();  //栈顶已经析构掉了,引用失效
	
	return 0;
}

deque(双端对列)

既可以在尾部插入,也可以在头部插入(栈没有迭代器,不能进行迭代)

int main()
{
	deque<int>deq;

	deq.push_back(12);
	deq.push_back(23);
	
	deq.push_front(100);
	deq.push_front(120);

	for (auto& x : deq)
	{
		cout << x << endl;
	}
}

queue

队列的底层实现可以为双端队列,或者list,但是不允许为vector,因为vector没有pop_front的方法

int main()
{
	queue<int, deque<int>>qu;
	queue<int, list<int>>lqu;

	lqu.push(12);
	lqu.push(23);

	int x = lqu.front();  //不要拿引用接受
	lqu.pop();
	cout << x << endl;
	//queue<int, std::vector<int>>vqu;  //不允许拿vector构建队列
}

priority_queue

int main()
{
	std::priority_queue<int,std::vector<int>,greater<int>>qu; //从小到大取元素(小堆序),默认大堆序
	qu.push(12);
	qu.push(23);
	qu.push(8);
	qu.push(34);
	qu.push(56);
	qu.push(3);

	while (!qu.empty())
	{
		int val = qu.top();
		qu.pop();
		cout << val << endl;
	}
}

map(重点)

底层实现(红黑树):关联容器。


template<class T1,class T2>
struct my_pair
{
	using first_type = T1;  //重命名
	using second_type = T2;

	first_type first;
	second_type second;
};

my_pair<int, string>myp{ 12, "hhh" };

template<class _Key,class _Val>
class my_map
{
	using value_type = my_pair<_Key, _Val>;
	struct _rbnode
	{
		value_type data;  //data.first=>Key data.second=>Value
	};
};

int main()
{
	//std::map<int, std::string>ismap;
	//       key       value

	//value_type由pair进行重命名
	std::map<std::string, int>simap;
	//关键码不允许重复
	simap.insert(std::map<std::string, int>::value_type("hhh",12));
	simap.insert(std::map<std::string, int>::value_type("ppp", 34));
	simap.insert(std::map<std::string, int>::value_type("rrr", 56));
	simap.insert(std::map<std::string, int>::value_type("www", 23));
	simap.insert(std::map<std::string, int>::value_type("aaa", 78));
	simap.insert(std::map<std::string, int>::value_type("bbb", 45));

	for (auto& x:simap)
	{
		cout << x.first << " " << x.second << endl;
	}
}

在这里插入图片描述

int main()
{
	using SIMP = std::map<std::string, int>;
	using ValType = std::map<std::string, int>::value_type;
	SIMP simap;
	simap.insert(ValType("hhh", 12));
	simap.insert(ValType("www", 23));
	simap.insert(ValType("rrr", 34));
	simap.insert(ValType("ttt", 21));
	simap.insert(ValType("uuu", 6));
	simap.insert(ValType("kkk", 10));


	for (auto& x : simap)
	{
		cout << x.first << " " << x.second << endl;
	}

	std::map<string, int, greater<string>>::iterator ita = simap.begin();
	auto it = simap.begin();  //可以直接用auto推导
	for (; it != simap.end(); ++it)
	{
		cout << it->first << " " << it->second << endl;
	}
}

at与operator[] 的区别:
at:通过关键码查询值,如果找不到,直接报错
operator[]:通过关键码查询值,如果找不到,则在红黑树中构建一个元素,并且将value的值赋值0
在这里插入图片描述
用map统计文件中单词的个数,并进行排序(状态机)

#define  _CRT_SECURE_NO_WARNINGS
#include<iostream>
#include<stdlib.h>
#include<stdio.h>
#include<deque>
#include<queue>
#include<stack>
#include<list>
#include<map>
using namespace std;

#define BEGIN 0
#define IN_WORD 1
#define OUT_WORD 2

int main()
{
	FILE* fp = fopen("day0513.cpp", "r");
	if (nullptr == fp)exit(EXIT_FAILURE);
	int const len = 256;
	char str[len] = {};
	int tag = BEGIN;
	int posi;
	std::map<string, int>simap;
	while (!feof(fp))
	{
		fgets(str, 256, fp);
		for (int i = 0; str[i] != '\0' && i < len; ++i)
		{
			switch (tag)
			{
			case BEGIN:
				if (isalpha(str[i]))
				{
					posi = i;
					tag = IN_WORD;
				}
				else
				{
					tag = OUT_WORD;
				}
				break;
			case IN_WORD:
				if (!isalpha(str[i]))
				{
					std::string word(&str[posi], i - posi); //i-posi分离出每个单词
					//cout << word << endl;
					simap[word] += 1;
					tag = OUT_WORD;
				}
				break;
			case OUT_WORD:
				if (isalpha(str[i]))
				{
					posi = i;
					tag = IN_WORD;
				}
				break;
			}
		}
	}
	fclose(fp);
	fp = nullptr;
	/*for (auto& x : simap)
	{
		cout << x.first << " " << x.second << endl;
	}*/
	std::multimap<int,string>ismap;
	for (auto& x :simap)
	{
		ismap.insert(std::multimap<int, string>::value_type(x.second, x.first));
	}

	for (auto& x : ismap)
	{
		cout << x.first << " " << x.second << endl;
	}
	return 0;
}

关于map的底层
在这里插入图片描述

为什么打印出来的数据为:12,23,34,45,56,67 ?
因为底层为中序遍历

unordered_map(底层哈希链表):与map的区别是在于关键码是否有序

map的插入:

int main()
{
	std::map<int ,string>age_namemap;
	int age;
	string name;
	while(cin>>age>>name,age>=16||name!="end")
	{
		age_namemap[age]=name;
		age_namemap.insert(std::map<int,string>::value_type(age,name));
		age_namemap.insert(pair<const int,string>(age,name));
		//age_namemap.insert(age,name);//error
	}
}

多重map:允许关键码重复。

find
在map中进行查找,找到则返回该关键码迭代器,未找到则返回simap.end()

int main()
{
	std::map<string,int>simap;
	simap["aaa"]=20;
	simap["bbb"]=21;
	simap["ccc"]=22;
	
	std::map<string,int>::iterator it=simap.find("aaa");
	//std::map<string,int>::iterator it=simap.find("nnn");
	if(it!=simap.end())
	{
		cout<<it->first<<" "<<it->second<<endl;
	}
	else
	{
		cout<<"no key"<<endl;
	}
	return 0;
}

equal_range
在这里插入图片描述

  • 返回容器中所有拥有给定关键元素的范围
  • 范围以第二个迭代器定义
  • 一个指向首个不小于key的元素
  • 另一个指向首个大于key的元素
  • 首个迭代器可以换用lower_bound()获得
  • 而第二个迭代器可以换用upper_bound()获得
int main()
{
	std::map<int ,std::string>ismap;
	ismap[12]="hhh";
	ismap[34]="ttt";
	ismap[23]="qqq";
	ismap[67]="zzz";
	ismap[45]="ddd";
	ismap[56]="aaa";
	auto it=ismap.equal_range(45);
	auto Lt=ismap.lower_bound(45);
	auto Rt=ismap.upper_bound(45);
	
	auto p=ismap.begin();
	for(;p!=ismap.begin();++p)
	{
		cout<<p->first<<endl;
	}
}

在这里插入图片描述

在这里插入图片描述

multimap多重map(底层红黑树)

int main()
{
	std::multimap<int,std::string>ismap;
	ismap.insert(std::multimap<int,std::string>::value_type(18,"aaa"));
	ismap.insert(std::multimap<int,std::string>::value_type(20,"bbb"));
	ismap.insert(std::multimap<int,std::string>::value_type(18,"ccc"));
	ismap.insert(std::multimap<int,std::string>::value_type(21,"ddd"));
	ismap.insert(std::multimap<int,std::string>::value_type(34,"eee"));
	ismap.insert(std::multimap<int,std::string>::value_type(23,"fff"));
	ismap.insert(std::multimap<int,std::string>::value_type(23,"ggg"));
	ismap.insert(std::multimap<int,std::string>::value_type(22,"hhh"));
	ismap.insert(std::multimap<int,std::string>::value_type(26,"mmm"));

	auto it=ismap.equal_range(18);
	for(auto p=it.first;p!=it.second;++p)
	{
		cout<<p->first<<"---->"<<p->second<<endl;
	}
}

在这里插入图片描述

set(去重)

set:底层也是红黑树实现的
set中的元素排好序了
set容器中没有重复的元素

insert
在这里插入图片描述


int main()
{
	std::set<int>iset;
	for (int i = 0; i < 100; ++i)
	{
		auto it = iset.insert(rand() % 100);
		if (it.second)
		{
			cout << "insert 成功" << endl;
		}
		else
		{
			cout << "已经有重复值" << *it.first <<endl;
		}
	}
	std::set<int>::iterator it = iset.begin();
	for (; it != iset.end(); ++it)
	{
		cout << *it << endl;
	}
}

map与unordered_map的区别

int main()
{
	std::map<int, std::string>ismap;
	std::unordered_map<int, std::string>isunmap;

	ismap[12] = "hhh";
	ismap[34] = "ttt";
	ismap[23] = "qqq";
	ismap[67] = "zzz";
	ismap[45] = "ddd";
	ismap[56] = "aaa";

	isunmap[12] = "hhh";
	isunmap[34] = "ttt";
	isunmap[23] = "qqq";
	isunmap[67] = "zzz";
	isunmap[45] = "ddd";
	isunmap[56] = "aaa";
	cout << "map" << endl;
	for (auto& x : ismap)
	{
		cout << x.first << " " << x.second << endl;
	}
	cout << "------------------" << endl;
	for (auto& x : isunmap)
	{
		cout << x.first << " " << x.second << endl;
	}
}

在这里插入图片描述
无序map的底层是哈希表
在这里插入图片描述

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

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

相关文章

EDA数字钟(三)

文章目录 前言一、设计内容二、模块结构三、代码编写1、顶层模块Digclk2、状态控制模块Ctrl3、按键消抖模块Filter4、计时模块Time5、闹钟模块Alarm6、显示模块Display7、数码管驱动模块Smg 四、测试文件五、波形仿真总结 前言 再次编写数字钟Verilog程序&#xff0c;使其符合…

数据迁移工具,用这8种就够了

前言 最近由于工作需要需要进行数据迁移&#xff0c;那么ETL数据迁移工具该用哪些呢&#xff1f; ETL(是Extract-Transform-Load的缩写&#xff0c;即数据抽取、转换、装载的过程)&#xff0c;对于企业应用来说&#xff0c;我们经常会遇到各种数据的处理、转换、迁移的场景。…

50 Projects 50 Days - Split Landing Page 学习记录

项目地址 Split Landing Page 展示效果 Split Landing Page 实现思路 当鼠标移动到左右两块区域时&#xff0c;分别给容器添加不同的class实现样式的变换。 有两种思路可以实现&#xff0c;一种是hover时改变宽度&#xff0c;一种是hover时改变flex拉伸比例&#xff0c;两…

从零手写操作系统之RVOS外设中断实现-04

从零手写操作系统之RVOS外设中断实现-04 RISC-V 中断&#xff08;Interrupt&#xff09;的分类RISC-V Trap &#xff08;中断&#xff09;处理中涉及的寄存器寄存器 mie、mip中断处理流程PLIC 介绍外部中断&#xff08;external interrupt &#xff09;PLICPLIC Interrupt Sour…

精调万分(Fine tune SAM)-万分预测器的解读和精调之一

缘起 分割万物(segment-anything model, SAM, 万分), 是图像分割领域的革命, 图像分割从此进入大模型时代. 如何自定义这个大模型以为己用? 或者说, 通过精调取长补短用于自己的项目?这是一个值得研究的问题, 在这里我试着探索一下, 万分在医学影像学里面的脊柱分割的应用. …

【sentinel】滑动时间窗口算法在Sentinel中的应用

固定窗口算法&#xff08;计数器法&#xff09; 算法介绍 计数器法是限流算法里最简单也是最容易实现的一种算法。比如我们规定&#xff0c;对于A接口来说&#xff0c;我们1秒的访问次数不能超过10次。那么我们可以这么做&#xff1a;在一开始的时候&#xff0c;我们可以设置…

ESP-BOX官方例程实践

1.下载esp-box项目代码 github仓库&#xff1a;https://github.com/espressif/esp-box gitee仓库&#xff1a;https://gitee.com/EspressifSystems/esp-box 使用git工具和如下命令进行下载&#xff1a; git clone --recursive https://github.com/espressif/esp-box.git or gi…

【C++ 基础篇:21】:friend 友元四连问:什么是友元?友元类?友元函数?什么时候用友元?

本系列 C 相关文章 仅为笔者学习笔记记录&#xff0c;用自己的理解记录学习&#xff01;C 学习系列将分为三个阶段&#xff1a;基础篇、STL 篇、高阶数据结构与算法篇&#xff0c;相关重点内容如下&#xff1a; 基础篇&#xff1a;类与对象&#xff08;涉及C的三大特性等&#…

S7-200 PLC的CPU模块介绍

更多关于西门子S7-200PLC内容查看&#xff1a;西门子200系列PLC学习课程大纲(课程筹备中) 1.什么是西门子200PLC的CPU? 如下图1-1所示&#xff0c;S7-200 PLC CUP是将一个微处理器&#xff0c;一个集成电源&#xff0c;一定的数字量或模拟量I/O&#xff0c;一定的通信接口等…

【Linux】—— git的管理以及使用

前言&#xff1a; 在上篇我们已经学习了关于调试器gdb的相关知识&#xff0c;本期我将为大家介绍的是关于版本控制工具——git的使用教程&#xff01;&#xff01;&#xff01; 目录 前言 &#xff08;一&#xff09;git的历史介绍 &#xff08;二&#xff09;github和gite…

Unity异步编程【6】——Unity中的UniTask如何取消指定的任务或所有的任务

今天儿童节&#xff0c;犬子已经9个多月了&#xff0c;今天是他的第一个儿童节。中年得子&#xff0c;其乐无穷&#xff08;音&#xff1a;ku bu kan yan&#xff09;…回头是岸啊 〇、 示例效果 一连创建5个异步任务[id 从0~4]&#xff0c;先停止其中的第id 4的任务&#x…

Flutter进阶篇-布局(Layout)原理

1、约束、尺寸、位置 overrideWidget build(BuildContext context) {return Scaffold(body: LayoutBuilder(builder: (context, constraints) {print("body约束:" constraints.toString());return Container(color: Colors.black,width: 300,height: 300,child: L…

【企业化架构部署】基于Nginx搭建LNMP架构

文章目录 一、安装 MySQL 数据库1. 安装Mysql环境依赖包2. 创建运行用户3. 编译安装4. 修改mysql 配置文件5. 更改mysql安装目录和配置文件的属主属组6. 设置路径环境变量7. 初始化数据库8. 添加mysqld系统服务9. 修改mysql 的登录密码10. 授权远程登录 二、编译安装 nginx 服务…

Maven 工具

Maven 工具 Maven简介Maven 基础概念创建 Maven项目依赖配置生命周期与插件分模块开发聚合和继承聚合继承聚合与继承的区别 属性版本管理多环境配置与应用私服 Maven简介 Maven 本质是一个项目管理工具&#xff0c;将项目开发和管理过程抽象成一个项目对象模型&#xff08;POM…

【爬虫】3.4爬取网站复杂数据

1. Web服务器网站 进一步把前面的Web网站的mysql.html, python.html, java.html丰富其中 的内容&#xff0c;并加上图形&#xff1a; mysql.html <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><title>my…

ICV报告: 智能座舱SoC全球市场规模预计2025年突破50亿美元

在智能化、互联化车辆需求不断增加的推动下&#xff0c;汽车行业正在经历一场范式转变。这一转变的前沿之一是智能座舱SoC。本市场研究报告对智能座舱SoC市场进行了全面的分析&#xff0c;包括其应用领域、当前状况和主要行业参与者。 智能座舱SoC指的是现代汽车智能座舱系统的…

Qt6.5.1+WebRTC学习笔记(十)开发环境搭建(win10+vs2022)

一、准备 1.操作系统win10 64位 2.合理的上网方式&#xff0c;需要正常访问google,最好有40G以上流量 3.安装VS2022&#xff0c;笔者使用的是社区版&#xff0c;并选中C相关&#xff0c;笔者设置如下 注意&#xff0c;win10的sdk需要是10.0.22621.0&#xff0c;其他版本可能…

吴恩达 ChatGPT Prompt Engineering for Developers 系列课程笔记--06 Transforming

06 Transforming 大语言模型&#xff08;LLM&#xff09;很擅于将输入转换为不同格式的输出&#xff0c;比如翻译、拼写校正或HTML格式转化。相比于复杂的正则表达式&#xff0c;Chat GPT实现更加准确和高效。 1) 不同语种的转换 下述语句实现了英文到西班牙语的翻译。 pro…

Windows IIS/docker+gunicorn两种方式部署django项目

写在最前 本篇文章并不涉及如何使用宝塔搭建django项目&#xff0c;仅适用于windows和docker部署&#xff0c;其中docker是运行在linux平台上的&#xff0c;如果您想在windows上运行docker&#xff0c;请自行搜索如何在windows上运行docker 一、Windows IIS部署 软件版本Win…

MySQL-Linux版安装

MySQL-Linux版安装 1、准备一台Linux服务器 云服务器或者虚拟机都可以&#xff1b; Linux的版本为 CentOS7&#xff1b; 2、 下载Linux版MySQL安装包 下载地址 3、上传MySQL安装包 使用FinalShell软件上传即可&#xff01; 4、 创建目录,并解压 mkdir mysqltar -xvf my…