C++STL库之map

文章目录

  • 关于仿函数
  • 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的底层是哈希表
在这里插入图片描述

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

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

相关文章

2022年长三角高校数学建模竞赛C题隧道的升级改造与设计解题全过程文档及程序

2022年长三角高校数学建模竞赛 C题 隧道的升级改造与设计 原题再现&#xff1a; 某地现存一旧式双洞隧道&#xff0c;现计划将该隧道在旧貌基础上升级改造。在升级改造前&#xff0c;需进行定标与设计。考虑到该隧道洞壁附着特殊涂料&#xff0c;无人机在洞内通信信号较差&am…

LIBEVENT 框架

LIBEVENT 框架 LAMPlibevent特点:libevent的功能libevent官网安装步骤Linux下libevent主要API介绍libevent使用步骤libevent 编程案例LAMP 从LAMP说起: 是一个缩写,它指一组通常一起使用来运行动态网站或者服务器的自由软件 Linux - 操作系统Apache - 网页服务器MySQL - 数据…

基于Yolov5目标检测的物体分类识别及定位(一) -- 数据集原图获取与标注

从本篇博客正式开始深度学习项目的记录&#xff0c;实例代码只会放通用的代码&#xff0c;数据集和训练数据也是不会全部放出。 系列文章&#xff1a; 基于Yolov5目标检测的物体分类识别及定位&#xff08;一&#xff09; -- 数据集原图获取与标注 基于Yolov5目标检测的物体分类…

Data Distillation: A Survey

本文是蒸馏学习综述系列的第二篇文章&#xff0c;Data Distillation: A Survey的一个翻译 数据蒸馏&#xff1a;综述 摘要1 引言2 数据蒸馏框架2.1 元模型匹配的数据蒸馏2.2 梯度匹配的数据蒸馏2.3 轨迹匹配的数据蒸馏2.4 分布匹配的数据蒸馏2.5 因式分解的数据蒸馏 3 数据模态…

python中Requests发送json格式的post请求方法

问题&#xff1a;做requests请求时遇到如下报错&#xff1a; {“code”:“500”,“message”:"JSON parse error: Cannot construct instance of com.bang.erpapplication.domain.User (although at least one Creator exists): no String-argument constructor/factory …

16.2:岛屿数量问题

文章目录 岛屿数量问题方法一&#xff1a;采用递归的方法方法二&#xff1a;使用并查集的方法&#xff08;map&#xff09;方法三&#xff1a;使用并查集的方法&#xff08;数组&#xff09; 岛屿数量问题 测试链接&#xff1a;https://leetcode.com/problems/number-of-islan…

C++ string类-2

at at 函数是在C还没有支持运算符重载的时候提供的。 他可以像 [] 重载运算符一样&#xff0c;找到某个位置的字符&#xff1a; string s1("hello world");s1.at(0) x;cout << s1 << endl; 输出&#xff1a; [] 重载运算符和 at&#xff08;&#x…

8自由度并联腿机器狗实现行走功能

1. 功能说明 本文示例将实现R309a样机8自由度并联腿机器狗行走的功能。 2. 并联仿生机器人结构设计 机器狗是一种典型的并联仿生四足机器人&#xff0c;其腿部结构主要模仿了四足哺乳动物的腿部结构&#xff0c;主要由腿部的节段和旋转关节组成。在设计机器狗的腿部结构时&…

echart实现地图展示

最近做的页面中需要展示省级地图精确到市级且悬浮到地区上时会显示一些信息 然后参考了网址&#xff1a; “绿色金融” - 江西省 - category-work,geo地理坐标,legend,series-map地图,series-scatter散点图,title标题,tooltip提示框,visualMap视觉映射 - makeapie echarts社区…

【玩转Linux操作】硬链接和软连接

&#x1f38a;专栏【玩转Linux操作】 &#x1f354;喜欢的诗句&#xff1a;更喜岷山千里雪 三军过后尽开颜。 &#x1f386;音乐分享【Counting Stars 】 欢迎并且感谢大家指出小吉的问题&#x1f970; 欢迎大家访问“在下小吉.”&#xff08;偷偷告诉你这个是我的大号哦&#…

yolov8seg模型转onnx转ncnn

yolov8是yolo的最新版本&#xff0c;可做图像分类&#xff0c;目标检测&#xff0c;实例分割&#xff0c;姿态估计。 主页地址 这里测试一个分割模型。 模型如下 选yolov8n-seg模型&#xff0c;转成onnx&#xff0c;再转ncnn测试。 yolov8s-seg的ncnn版可以直接用这个 如果用…

【Django 网页Web开发】07. 快捷的表单生成 Form与MoudleForm(保姆级图文)

目录 注意 正规写法是 ModelForm&#xff0c;下面文章我多实现效果url.py新建3个html文件数据库连接model.py 数据表1. 原始方法view.pytestOrgion.html 2. Form方法view.pytestForm.html 3. MoudleForm方法给字段设置样式面向对象的思路&#xff0c;批量添加样式错误信息的显示…

搜索算法(三) 回溯法

1.回溯法 回溯法可以理解成一种特殊的深度优先算法&#xff0c;比起普通的DFS&#xff0c;多了还原当前节点的一步。 修改当前节点、递归子节点、还原当前节点。 本质是一种试错的思想。 维基百科&#xff1a; 2.例题 1&#xff09; 力扣https://leetcode.cn/problems/pe…

17_Linux根文件简介与Busybox构建文件系统

目录 根文件系统简介 文件目录简介 BusyBox简介 编译BusyBox构建根文件系统 修改Makefile添加编译器 busybox中文字符支持 配置 busybox 编译busybox 向根文件系统添加lib库 向rootfs的“usr/lib”目录添加库文件 创建其他文件夹 根文件系统初步测试 根文件系统简介…

行业应用|立仪光谱共焦位移传感器在玻璃方面的检测

项目&#xff1a;玻璃管管壁单边测厚 行业应用|立仪光谱共焦位移传感器在玻璃方面的检测 行业应用|立仪光谱共焦位移传感器在玻璃方面的检测 检测方案 用D35A7镜头对玻璃管管壁进行单边测厚&#xff0c;取三个点静态测量厚度并记录重复性。 1、采用D35A7R2S35镜头对玻璃管管…

Android Input子系统 - kernel

目录 前言 数据结构 输入子系统流程 前言 上一节有展示Android Input子系统的架构图,这里我们关心Linux kernel层 可以看到kernel层分为三层: 输入子系统设备驱动:处理与硬件相关的信息,调用input API注册输入设备,并把数据往上报 输入子系统核心层:为事件处理层和设…

Python之并发多线程操作

一、threading模块介绍 multiprocess模块的完全模仿了threading模块的接口&#xff0c;二者在使用层面&#xff0c;有很大的相似性 二、开启线程的两种方式 方式一 #方式一 from threading import Thread import time def sayhi(name):time.sleep(2)print(%s say hello %na…

迷你版ChatGPT开源,教你怎么用nanoGPT训练一个写小说的AI机器人!

大家好,我是千与千寻,好久不见,最近太忙了,去医院拔了颗智齿,这不是刚休息一天,就立刻来给大家分享ChatGPT的新奇项目了。 ChatGPT的功能确实是好用,但是我觉得有一个小缺点,就是反应的时间比较慢,原因是GPT-3.5/GPT-4.0的模型体积较大,比较占用内存空间。 同时大模…

10.ES6模块化规范(关键字 import,from,as,export的用法)

导入其他模块成员要使用关键字 import &#xff0c;导出需要使用关键字 export 我们明确一个概念&#xff0c;只有js与js之间需要使用import与export&#xff0c;如果是在html中引入js是不需要用import的&#xff0c;你导入的方式是直接srcxxx.js 目录 1 默认导入导出 2 …

【高危】Apache Inlong 存在JDBC反序列化漏洞

漏洞描述 Apache InLong 是可用于构建基于流式的数据分析、建模等一站式的海量数据集成框架。 在Apache Inlong受影响版本&#xff0c;由于未对接收的jdbcUrl参数过滤空格字符&#xff0c;导致可以利用空格绕过jdbcUrl中autoDeserialize参数过滤限制&#xff0c;通过认证的攻…