Map的使用

引言

STL介绍

STL(Standard Template Library,标准模板库)是c++标准模版库的一部分。它为开发者提供了大量通用的数据结构、算法以及用于操作这些数据结构的工具。
STL的设计原则是将数据结构与操作这些数据结构的算法分离,使得两者可以独立地复用。
STL主要成分包括:
容器:如向量(vector)、列表(list)、栈(stack)、队列(queue)、集合(set)、映射(map)等,用于存储和组织数据。
迭代器:用于遍历容器中的元素,类似于指针,但更加通用,可以用于不同类型的容器。
算法:提供了一系列可作用于容器上的操作,如查找(search)、排序(sort)、复制(copy)等。
STL的设计使得C++程序员能够快速开发出高效且健壮的应用程序,而无需从零开始实现常见的数据结构和算法。此外,STL支持泛型编程,这意味着它可以处理任何类型的数据,提高了代码的重用性和灵活性。
本篇博客主要介绍map和set

容器

在stl中,容器主要分为两大类:序列式容器和关联式容器。
序列式容器按线性顺序存储元素。常见序列式容器例如:vector、deque、list、array
关联式容器按照关键字排序存储元素,里面存储的是<key,value>结构的键值对。通常不允许关键字key重复(multiset、multimap除外)。常见关联式容器包括map、set、multiset、multimap

pair

std::pair<T1,T2>是c++标准库一个模板类,用于表示一对元素。它通常被用来表示键值对。
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& _M_first, const T2& _M_second)
      : first(_M_first), second(_M_second) {}

    // 比较运算符
    bool operator==(const pair& __p) const;
    bool operator!=(const pair& __p) const;
    bool operator<(const pair& __p) const;
    bool operator<=(const pair& __p) const;
    bool operator>(const pair& __p) const;
    bool operator>=(const pair& __p) const;

    // 更多的成员函数...
};

pair使用场景:
坐标点:表示一个二维坐标 (x, y)。
范围:表示一个范围 (start, end)。
键值对:表示一个键值对 (key, value)。
其他组合:表示任意两个相关联的值。
std::pair作为键值对
在 std::map 中,每个元素都是一个 std::pair<const Key, T>,表示一个键值对。这里的 Key 是键的类型,T 是值的类型。

第一部分:了解map

map是什么?

map是关联式容器,按照特定次序(key的比较)存储由键值(key)和值(value)组合而成的元素。
map的底层实现通常是一个自平衡二叉搜索树(最常见的是红黑树)
在map中,键值key通常用于排序和唯一的标识元素,value中存储与键值key相关联的内容。key与value的类型可能不同。在map内部,key与value通过成员类型pair<const Key,T>绑定在一起,取别名为value_type.
在这里插入图片描述
从这里我们也可以看出,map的key不可以修改的,但是value可以修改

如何使用map

这是map模版参数说明
在这里插入图片描述
我们可以看到,在实际使用中,我们一般只需要注意传入key和value的类型即可,如果传入的key为自定义类型,那么还需要用户显示传递自己的比较规则。
使用map的时候,需要包含头文件

如何定义并初始化一个map对象

下面让我们定义一个map对象
我们可以使用初始化列表,operator[] 或者是insert函数

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

void TestMap()
{
	//初始化列表初始化
	map<int, int> m1 = { {1,2},{2,4},{3,8} };
	map<int, double> m2;//声明对象m2 使用下标访问符
	m2[3] = 3.0;
	m2[0] = 0.0;
	m2[9] = 9.0;
	//也可以使用insert函数
	m2.insert(make_pair(1, 1.1));
	cout << "m2" << "-> ";
	for (auto e : m2)
	{
		cout << e.first << ":" << e.second<< " ";
	}
	cout << endl;

}

int main()
{
	//Map测试
	TestMap();
	return 0;
}

不同类型的键值对示例

在这里插入图片描述

map的关键特性

1.map中的元素是键值对,其中键值唯一不可以被修改
2.map中元素排列顺序按照key进行比较
3.map中元素用迭代器去遍历,可以得到一个有序的序列
(可以使用map进行排序+去重)
4.map支持下标访问

遍历map中的元素

可以使用迭代器或者范围for

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

int main()
{
	vector<string> v = { "xaiomin","xiaowang","maomi","lihua","mike","kimi","timi" };
	map<int, string> m;
	int i = 0;
	for (auto e : v)
	{
		m[i++] = e;
	}
    //迭代器
	map<int, string> ::iterator it = m.begin();
	while (it != m.end())
	{
		cout << it->second << " ";
		it++;
	}
	cout << endl;
    //范围for
	for (auto e : m)
	{
		cout << e.second << " ";
	}
	cout << endl;
	return 0;
}

map函数使用

增加和删除元素

Insert在这里插入图片描述
函数使用:
在这里插入图片描述

在map中插入键值对x(你想插入的),返回一个键值对在这里插入图片描述
返回的键值对中的iterator 指向你新插入元素的位置,bool为true表示插入元素成功,如果在插入的时候发现已经存在一个相等的key,就返回false。
代码测试:
在这里插入图片描述
插入后:
在这里插入图片描述

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

void TestMap()
{

	map<string, string> m3;
	//插入
	//使用insert插入元素 匿名插入
	m3.insert(pair<string, string>{ "apple", "苹果" });
	//显式插入
	pair<string, string> p = { "watermelon", "西瓜" };
	m3.insert(p);
	//make_pair函数
	m3.insert(make_pair("strawberry", "草莓"));
	//下标访问符
	m3["banana"] = "香蕉";

	//插入重复元素 apple haha
	pair<map<string, string>::iterator, bool> ret = m3.insert(make_pair("apple", "haha"));
	if (ret.second) //插入成功
	{
		cout << ret.first->first << ":" << ret.first->second << ":" << ret.second << endl;
		//此处 ret为键值对,第一个元素是指向map中一个元素的指针,该元素也是键值对,想访问需要指针解引用,下同
	}
	else
	{
		cout << ret.first->first << ":" << ret.first->second << ":" << ret.second << endl;
	}

	//插入不重复元素
	ret = m3.insert(make_pair("HAHA", "haha"));

	if (ret.second) //插入成功
	{
		cout << ret.first->first << ":" << ret.first->second << ":" << ret.second << endl;
		//此处 ret为键值对,第一个元素是指向map中一个元素的指针,该元素也是键值对,想访问需要指针解引用,下同
	}
	else
	{
		cout << ret.first->first << ":" << ret.first->second << ":" << ret.second << endl;
	}
	
	//遍历打印所有的元素
	map<string, string> ::iterator it = m3.begin();
	//使用迭代器进行打印
	while (it != m3.end())
	{
		cout << it->first << ":" << it->second << " ";
		it++;
	}
	cout << endl;
}

int main()
{
	//Map测试
	TestMap();
	return 0;
}

删除元素Erase
在这里插入图片描述
三种删除方式,删除指定键值,删除指定位置,删除区间元素
其中删除指定键值有返回值,为删除的元素个数,该返回值在map中没什么用处,在multimap中可以用来统计个数(map元素插入的时候会去重,但是multimap不会,multimap是真正意义上排序)

#include<iostream>
using namespace std;
#include<map>
void PrintMap(map<string, string> m)
{
	for (auto e : m)
	{
		cout << e.first << ":" << e.second << " ";
	}
	cout << endl;
}


void TestMap()
{
	map<string, string> m3;
	map<string, string>::iterator it;
	//插入
	//使用insert插入元素 匿名插入
	m3.insert(pair<string, string>{ "apple", "苹果" });
	//显式插入
	pair<string, string> p = { "watermelon", "西瓜" };
	m3.insert(p);
	//make_pair函数
	m3.insert(make_pair("strawberry", "草莓"));
	//下标访问符
	m3["banana"] = "香蕉";

	PrintMap(m3);
	it = m3.begin();
   
	//删除元素
	//删除键值为某个值的元素
	m3.erase("banana");
	PrintMap(m3);

	//删除某个位置上的元素(这个传入的位置必须有效)
	m3.erase(it); 
	PrintMap(m3);
	it = m3.begin();
	//删除区间上的值
	m3.erase(m3.begin(),m3.end());
	PrintMap(m3);
}

int main()
{
	//Map测试
	TestMap();
	return 0;
}

在这里插入图片描述

查找和修改元素

Find查找
在这里插入图片描述
(1)在这里插入图片描述

在map中查找key为x的元素,找到返回该元素的位置的迭代器,否则返回end()
(2)在这里插入图片描述

在map中查找key为x的元素,找到返回该元素的位置const迭代器,否则返回cend()
两种find的主要区别在于返回的迭代去是否可以用来修改元素。
修改元素
使用下标访问符进行修改,或者find查找元素是否存在,然后再进行修改
在这里插入图片描述

map中的下标访问符

在C++中,std::map 容器提供了 operator[] 成员函数,它允许用户像访问数组一样使用方括号来访问键值对。这个操作符被称为“索引运算符”或“下标运算符”。

operator[] 主要有两个作用
1.如果给定的键存在于 std::map 中,则返回与该键关联的值类型的引用。
2.如果给定的键不存在,则会插入一个新的键值对,其中键就是提供的键,而值是值类型的默认构造对象,并返回这个新插入元素的值部分的引用。

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

void PrintMap(map<int, string>  m)
{
	//遍历元素
	map<int, string> ::iterator it = m.begin();
	while (it != m.end())
	{
		cout <<it->first<< ":" <<  it->second << " ";
		it++;
	}
	cout << endl;
}

int main()
{
	vector<string> v = { "xaiomin","xiaowang","maomi","lihua","mike","kimi","timi" };
	map<int, string> m;
	int i = 0;
	for (auto e : v)
	{
		m[i++] = e;
	}

	PrintMap(m);

	//访问已经存在的元素
	m[0] = "damin";
	PrintMap(m);
	//访问不存在的元素
	m[8] = "xiaocao";
	PrintMap(m);
	return 0;
}

在这里插入图片描述

其他的函数

swap:交换两个map的元素
clear:map中的元素清空
count:返回key为x的键值在map中的个数(主要用于multimap)

关于map更多知识

第二部分:了解multimap

multimap定义:

multimap也是关联式容器,底层应用二叉搜索树。按照特定的顺序存储键值对<key,value>,通过key排序并且标识元素。其中,多个键值对之间的key是可以重复的。使用迭代器遍历multimap可以得到有序的序列。

multimap特点:

1.key可以重复
2.multimap中的元素默认key按照小于来比较
3.multimap不可以使用下标访问
4.使用时包含#include<map>即可

multimap使用:

与map基本相同。
关于multimap更多知识

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值