C++容器——字典(map)

1. 简介

map是一种关联式容器,包含唯一的键值对,即 (key, value),内部会根据key值进行排序;增加、修改和查询具有对数的时间复杂度,其存储结构为红黑树;

头文件和定义

//头文件
#include <map>

//定义
template<
    class Key,
    class T,
    class Compare = std::less<Key>,
    class Allocator = std::allocator<std::pair<const Key, T>>
> class map;

2. 初始化

map的初始化方法如下所示

/*
* @brief map
* g++ -g map_main.cc -o d -std=c++11
*
*/
#include <iostream>
#include <map>
#include <iterator>
#include <string>
#include <algorithm>

template<typename T>
void showInfo(T &t)
{
	auto iter = t.begin();
	while (iter != t.end())
	{
		std::cout<<iter->first<<"   "<<iter->second<<std::endl;
		iter++;
	}
	std::cout<<std::endl;	
}

int main(int argc, char *argv[])
{
	std::map<int32_t, std::string> m1;
	m1.insert({2,"c"});
	m1.insert({4,"c++"});
	m1.insert({5,"python"});
	showInfo(m1);

	std::map<int32_t, std::string> m2{{1,"student"},{4,"teacher"},{3,"boy"},{2,"girl"}};
	showInfo(m2);

	std::map<int32_t, std::string> m3;
	m3.insert(std::pair<int32_t, std::string>(2,"windows"));   //pair
	m3.insert(std::pair<int32_t, std::string>(3,"linux"));
	m3.insert(std::make_pair(1,"mac"));   //make_pair
	m3.insert(std::make_pair(5,"unix"));  //
	showInfo(m3);

	std::map<int32_t, std::string> m4 = m1;
	showInfo(m4);
	m4[10] = "shell";	//元素的添加
	m4[7] = "Rust";
	m4[5] = "Java";    //会替换(5, python)
	showInfo(m4);

	return 0;
}

输出

2   c
4   c++
5   python

1   student
2   girl
3   boy
4   teacher

1   mac
2   windows
3   linux
5   unix

2   c
4   c++
5   python

2   c
4   c++
5   Java
7   Rust
10   shell

3. 使用

3.1 元素访问

方法说明
at()元素访问
operator[]元素访问
iterator可以访问元素,也可以遍历字典中的元素

示例

int main(int argc, char *argv[])
{
	//元素访问
	std::map<int32_t, std::string> m1{{1,"student"},{4,"teacher"},{3,"boy"},{2,"girl"}};
	std::cout<<"m1[2] value is: "<<m1.at(1)<<std::endl;   //at 越界会抛出异常
	std::cout<<"m1[1] value is: "<<m1[1]<<"\n\n";      //[] 不会抛出异常
	auto iter = m1.begin();
	std::cout<<"iter->first value is: "<<iter->first<<"\n";      //迭代器输出key值
	std::cout<<"iter->second value is: "<<iter->second<<"\n";    //迭代器输出value值

	return 0;
}

输出

m1[2] value is: student
m1[1] value is: student

iter->first value is: 1
iter->second value is: student

3.2 元素的大小

方法说明
empty数组判空
size字典大小
max_size最大容量
clear清空map的大小
swap交换两个map的内容

示例

template<typename T>
void showInfo(T &t)
{
	auto iter = t.begin();
	while (iter != t.end())
	{
		std::cout<<"["<<iter->first<<", "<<iter->second<<"]; ";
		iter++;
	}
	std::cout<<std::endl;	
}

int main(int argc, char *argv[])
{	
	std::map<int32_t, std::string> m1{{1,"student"},{4,"teacher"},{3,"boy"},{2,"girl"}};	

	std::cout<<"size value is: "<<m1.size()<<"\n";
	std::cout<<"max_size value is: "<<m1.max_size()<<"\n\n";	

	std::map<int32_t, std::string> m2{{2,"c++"},{1, "c"}};
	m1.swap(m2);
	showInfo(m1);
	showInfo(m2);

	m1.clear();
	if(m1.empty())
	{
		std::cout<<"m1 empty"<<"\n";
	}
	else{
		std::cout<<"m1 not empty"<<"\n";
	}
	return 0;
}

结果

size value is: 4
max_size value is: 256204778801521550

[1, c]; [2, c++];
[1, student]; [2, girl]; [3, boy]; [4, teacher];
m1 empty

3.3 元素的修改

主要包括元素的赋值、插入和删除等

方法说明
=直接赋值
get_allocator返回内存分配器
insert插入元素
emplace插入元素
emplace_hint插入元素,需要写位置
tyr_emplace(C++17)插入元素
erase删除元素
extract(C++17)元素的删除,可以返回该值
merge(C++17)map的合并

示例

int main(int argc, char *argv[])
{	
	std::map<int32_t, std::string> m1{{1,"student"},{4,"teacher"},{3,"boy"},{2,"girl"}};	
	std::map<int32_t, std::string> m2{{2,"c++"},{1, "c"}};

	//1.元素插入
	m2.insert(std::make_pair(5,"linux"));
	m2.emplace(std::make_pair(7,"python"));
	m2.emplace_hint(m2.end(),std::make_pair(9,"golang"));   //本来就是自动排序	
	m2.try_emplace(10,"Rust");    
	showInfo(m2);

	//2.元素删除
	m2.erase(10);    //根据key值进行删除
	m2.erase(m2.begin());     //根据迭代器删除
	showInfo(m2);

	//3.extract
	m2.extract(m2.begin());
	showInfo(m2);
	std::cout<<std::endl;

	//4.merge
	m2.merge(m1);    //合并之后,m1是空的
	showInfo(m1);
	showInfo(m2);
	
	return 0;
}

结果

[1, c]; [2, c++]; [5, linux]; [7, python]; [9, golang]; [10, Rust];
[2, c++]; [5, linux]; [7, python]; [9, golang];
[5, linux]; [7, python]; [9, golang];


[1, student]; [2, girl]; [3, boy]; [4, teacher]; [5, linux]; [7, python]; [9, golang];

3.4 元素的操作

方法说明
count计算map中元素出现的次数
find查找元素
equal_range返回的是一个范围 [lower_bound, upper_bound]
lower_bound返回当前元素的位置,查找不到返回end
upper_bound返回当前元素的下一个位置,查找不到返回end
key_comp比较函数,key比较
value_comp比较函数,元素比较

示例

int main(int argc, char *argv[])
{	
	//1.count find 
	std::map<int32_t, std::string> m1{{1,"student"},{4,"teacher"},{3,"boy"},{2,"girl"}};	
	std::cout<<"[count]\n";
	std::cout<<m1.count(1)<<std::endl;

	auto au = m1.find(2);
	if(au == m1.end())
	{
		std::cout<<"not find"<<std::endl;
	}
	else{
		std::cout<<"find. the value is: "<<au->second<<std::endl;
	}

	//2. equal_range
	auto iter_equal = m1.equal_range(3);
	std::cout<<iter_equal.first->second<<std::endl;
	std::cout<<iter_equal.second->second<<std::endl;  //输出tearch 

	//3. lower_bound  upper_bound
	auto iter_lower = m1.lower_bound(3);
	std::cout<<iter_lower->second<<std::endl;

	auto iter_upper = m1.upper_bound(3);
	std::cout<<iter_upper->second<<std::endl;   //输出tearch 

	//4. key_comp
	auto keyComp = m1.key_comp();
	for(auto au : m1)
	{		
		if(keyComp(au.first, 2))
		{
			std::cout<<"true"<<" ";
		}
		else{
			std::cout<<"false"<<" ";
		}
	}
	std::cout<<std::endl<<std::endl;

	//5. value_comp
	auto valueComp = m1.value_comp();
	const std::pair<int, std::string> val = { 100, "a" };
	for(auto au : m1)
	{		
		if(valueComp(au, val))
		{
			std::cout<<"true"<<" ";
		}
		else{
			std::cout<<"false"<<" ";
		}
	}
	std::cout<<std::endl;	
	return 0;
}

输出

[count]
1
find. the value is: girl
boy
teacher
boy
teacher
true false false false

true true true true

3.5 迭代器

迭代器最好结合STL中的算法一起使用;迭代器的返回值最好用auto接收;

map的元素是pair,注意在访问元素的时候有firstsecond

迭代器的类型包括:iterator、const_iterator、reverse_iterator和const_reverse_iterator

方法说明
begin返回map的头元素(迭代器),其值可修改
end返回map的尾元素(迭代器),其值可修改
cbegin返回map的头元素(迭代器),其值不可修改,const属性
cend返回map的尾元素(迭代器),其值不可修改,const属性
rbegin反序返回map的头元素(迭代器),其值可修改,同end()
rend反序返回map的尾元素(迭代器),其值可修改,同begin()
crbegin反序返回map的头元素(迭代器),其值不可修改,同cend,const属性
crend反序返回map的头元素(迭代器),其值不可修改,同cbegin,const属性

迭代器的辅助函数
辅助函数的使用需要包含头文件

#include <iterator>
方法说明
advance移动迭代器的位置
distance计算两个迭代器的距离
begin返回容器第一个元素的迭代器
end返回容器最后一个元素的迭代器
prev迭代器向前移动一个元素
next迭代器向后移动一个元素
  • 0
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值