超详细介绍map(multimap)的使用

news/2025/2/25 22:46:40

map类的介绍

        map的声明如下,Key是map底层关键字的类型,T是map底层value的类型。set默认要求Key支持小于比较,如果不支持或者需要的情况下我们可以自行传入仿函数,map底层存储数据的内存是从空间申请来的。一般情况下,我们是不需要传后两个参数的。map的底层是由红黑树实现的,增删改查的效率是logN,迭代器遍历走的是中序,所以Key是有序排列的

        红黑树是平衡二叉搜索树

template < class Key,                                     // map::key_type
           class T,                                       // map::mapped_type
           class Compare = less<Key>,                     // map::key_compare
           class Alloc = allocator<pair<const Key,T> >    // map::allocator_type

pair类型介绍

        红黑树的节点类型是pair类型,使用pair<Key,T>存储数据

typedef pair<const Key, T> value_type;
template <class T1, class T2>
struct pair 
{
 typedef T1 first_type;
 typedef T2 second_type;
 T1 first;
 T2 second;
 
 pair(): first(T1()), second(T2 ())
 {}
 
 pair(const T1& a, const T2& b): first(a), second(b)
 {}
 
 template<class U, class V> 
 pair (const pair<U,V>& pr): first(pr.first), second(pr.second)
 {}
};
template <class T1,class T2>
inline pair<T1,T2> make_pair (T1 x, T2 y)
{
 return ( pair<T1,T2>(x,y) );
}

map的增删查

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

int main()
{
	map<string, string> m;

	//插入有名pair(方式一)
	pair<string, string> s("first", "第一个");
	m.insert(s);

	//插入无名piar(方式二)
	m.insert(pair<string, string>("second", "第二个"));

	//调用make_pair函数
	m.insert(make_pair("third", "第三个"));
	//make_pair函数,其功能为,将两个参数构造成一个pair并返回

	//隐式类型转化(c++11),可以看作将两个元素直接转化为pair
	m.insert({ "auto", "自动的" });

	// initializer_list构造
	map<string, string> dict = { {"left", "左边"}, {"right", "右边"},
{"insert", "插⼊"},{ "string", "字符串" } };

	
	//map的遍历
	//pair并没有重载流插入与流提取,故而下面的输出我们只能通过输出成员变量
	cout << "遍历一:" << endl;
	for (auto& e : m)
	{
		cout << e.first << "," << e.second << " ";
	}
	cout << endl;

	cout << "遍历二:" << endl;
	auto it = m.begin();
	while (it != m.end())
	{
		cout << it->first << "," <<it->second<< " ";
		it++;
	}
	cout << endl;


	//map的查找
	string str;
	cin >> str;
	auto pos = m.find(str);
	if (pos != m.end())
	{
		cout << "找到了:" << pos->first << "," << pos->second << endl;
	}
	else
	{
		cout << "不存在!"<<endl;
	}


	//map的删除
	cout << "删除一:" << endl;
	cin >> str;
	m.erase(str);
	for (auto& e : m)
	{
		cout << e.first << "," << e.second << " ";
	}
	cout << endl;

	cout << "删除二:" << endl;
	cin >> str;
	auto pos0 = m.find(str);
	m.erase(pos0);
	for (auto& e : m)
	{
		cout << e.first << "," << e.second << " ";
	}
	cout << endl;

	cout << "删除三:" << endl;
	//iterator  erase (const_iterator first, const_iterator last);
	//删除一段区间,给出左边迭代器和右边迭代器,函数将会删除这段区间,
	//一般搭配 lower_bound  upper_bound 使用
}

        

map的迭代器和[]功能

·        

        operator[]的功能:传入Key值会返回value值(传入pair的first,会返回pair的second)operator[]具有:插入、查找、修改的功能。需要注意的是,如果当传入的Key值本来就不存在map中时,这个值将会被插入map

        而operator[]之所以拥有这些功能与其底层(insert)的实现有关

        下面我们来仔细看看insert函数 

        insert的返回值为一个pair:

        当map中没有这个元素,insert插入成功并返回 pair<成功插入位置的迭代器,true>

        反之当map中有这个元素,insert插入失败并返回  pair<已经存在的值的迭代器,false>

具体实例:

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

int main()
{
	string arr[] = { "苹果", "西瓜", "苹果", "西瓜", "苹果", "苹果", "西瓜","苹果", "香蕉", "苹果", "香蕉" };  // 使用正确汉字 
	map<string, int> countMap;

	//普通统计水果数量的方式
	for (auto& e : arr)
	{
		auto pos=countMap.find(e);
		if (pos != countMap.end())
		{
			pos->second++;
		}
		else
		{
			countMap.insert({ e,1 });
		}
	}
	for (auto& e : countMap)
	{
		cout << e.first << "," << e.second<<" ";
	}
	cout << endl;


	//使用operator[]
	for (auto& e : arr)
	{
		countMap[e]++;
	}
	//若e存在则插入失败,operator[]返回value,再让其+1
	//若e不存在则插入成功{e,0},operator[]返回value,再让其+1 》{e,1}
	for (auto& e : countMap)
	{
		cout << e.first << "," << e.second << " ";
	}
	cout << endl;
	
}
#include<iostream>
#include<map>
using namespace std;

int main()
{
	map<string, string> dict;
	dict.insert(make_pair("sort", "排序"));

	// key不存在-> 插⼊ {"insert", string()} 
	dict["insert"];

	// key不存在-> 插⼊+修改 
	dict["left"] = "左边";

	// key已经存在-> 修改 
	dict["left"] = "左边、剩余";

	// key存在->查找 
	cout << dict["left"] << endl;
	return 0;
}

multimap和map的差异

        multimap和map的使⽤基本完全类似,主要区别点在于multimap⽀持关键值key冗余,那么 insert/find/count/erase都围绕着⽀持关键值key冗余有所差异,这⾥跟set和multiset完全⼀样,⽐如 find时,有多个key,返回中序第⼀个。其次就是multimap不⽀持[],因为⽀持key冗余,[]就只能⽀ 持插⼊了,不能⽀持修改。 


http://www.niftyadmin.cn/n/5865999.html

相关文章

手撕跳表/数据结构

昨天leetcode每日一题是跳表&#xff0c;之前学redis就没去写跳表&#xff0c;这次就逃不过了。 这里使用了len数组&#xff0c;来表示每个数字之间的间隔&#xff0c;方便复杂的查询功能。 主要问题有 为什么len数组记录的是数字之间的间隔&#xff0c;不是每一层从头到尾…

MFC学习笔记-1

一、编辑框和按钮 //.h文件private:CString str;//给窗口类加了一个变量&#xff08;定义一个成员变量&#xff09;&#xff0c;关联到IDC_EDIT1中&#xff08;要在实现中关联&#xff0c;源文件文件夹中&#xff09;CString str2;//接收button2&#xff0c;和IDC_EDIT2绑定 p…

Spring DIIoC

一.IoC 1.简介 什么是IoC&#xff1f;IoC&#xff0c;全称 Inversion of Control&#xff0c;控制反转。IoC是Spring的核心思想&#xff0c;Spring是⼀个“控制反转”的容器。 如果我们需要一个对象&#xff0c;正常来说我们是通过new一个对象&#xff0c;这个时候我们依赖的…

记录一下_treafik使用Gateway-APi使用的细节参数

一、这里说一下treafik最大的容易走入圈套的地方。 1、treafik默认不是hostnetwork模式。为了暴露自己出来它有一个LB类型的SVC。 这里的External_ip为我的节点IP&#xff0c;因为使用了k3s自带的LB&#xff0c;这个SVC就很容易绕进去。 1、第一个这个LB的作用是为了暴露treafi…

基于C#+SQL Server设计与实现的教学管理信息系统

教学管理信息系统 1、实验内容&#xff1a; 大学同时开设多门课程。每门课程有一个主讲教师&#xff0c;有多名学生选修&#xff1b;一个学生可选修多门课程并获得相应的学分和成绩&#xff1b;上课的基本单位是“次”&#xff08;一次 2 学时&#xff09;&#xff0c;每一次…

若依前后端分离框架修改3.8.9版本(重点在安全框架讲解与微信小程序登录集成)

若依模板改造&#xff08;3.8.9&#xff09; 1、基础改造 下载代码 从[RuoYi-Vue: &#x1f389; 基于SpringBoot&#xff0c;Spring Security&#xff0c;JWT&#xff0c;Vue & Element 的前后端分离权限管理系统&#xff0c;同时提供了 Vue3 的版本](https://gitee.co…

Flutter 实现抖音风格底部导航栏

在移动应用开发中&#xff0c;良好的导航设计对用户体验至关重要。抖音作为一款现象级应用&#xff0c;其底部导航设计简洁直观&#xff0c;极具吸引力。本文将详细介绍如何使用 Flutter 开发一个类似抖音风格的底部导航栏&#xff0c;帮助开发者打造兼具美观与实用的导航界面。…

找不到依赖项 <…> (Maven)

IDEA 的 build 操作和 maven 的 build 操作是分开的 重新加载 Maven 项目