map 学习(上)——C++中 map 的使用
2017-11-15 17:03
183 查看
map 学习(上)——C++中 map 的使用
欠下数据结构的债,迟早是要还的…… 最近写毕业论文过程中,需要用到哈希表的数据结构,此外空闲时间在刷 Leetcode 过程中,发现好多高效算法都是用 unordered_map 实现的,看来学习 map 相关内容是躲不了的了,开始学习 map 的相关内容。本篇先学习 C++ 中 STL 标准库中 map 的使用方法。
以下内容翻译自:《map - C++ Reference》
一、原型
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 > class map;
二、说明
map 是一种容器,用来存储若干元素,这些元素都是由关键值 (Key Value,以下称为 Key 值) 和映射值 (Mapped Value,以下依旧称为映射值) 配对组成的,具体说明如下:在一个 map 中, Key 值通常用来排序或特指元素,映射值用来存储与该 Key 值绑定的内容。 Key 值与映射值的数据类型可以不同,而且可以一起被放进成员类型 value_type 中,value_type 是一种配对类型,定义如下:
typedef pair<const Key, T> value_type;
在 map 内部的元素通常按照其 Key 值排序,且排序方式是根据某种明确、严格的弱排序标准进行的,这种排序标准是由 map 内部的比较对象(即 map::key_comp)指定的。
map 容器通过 Key 值访问特定元素的速度,相较于 unordered_map 容器通常较慢,但 map 容器允许基于它们的顺序对子集进行直接迭代。
map 中的映射值可以使用括号运算符 (operator[]) 通过其关联的 Key 值直接访问。
map 通常使用二叉搜索树实现。
三、map 容器属性
关联性:关联容器中的元素的参考地址指的是其 Key 值,而不是他们在容器中的绝对地址;
有序性:
容器中的元素一直按照排序方式严格排序,所有插入元素都按照该顺序排列;
映射:
每个元素中,一个 Key 值与一个映射值相关。Key 值是用来标识其主要内容是映射值的元素;
唯一 Key 值:
容器中不存在同时拥有相同 Key 值的两个元素;
分配感知 (Allocator-aware):
map 容器使用分配器对象动态处理其存储需求。
四、模板参数
KeyKey 值的类型。在 map 中的每个元素都是由其 Key 值唯一指定的。
别名为成员类型 map::key_type
T
映射值的类型。在 map 中的每个元素,都存储了一些数据作为其映射值。
别名为成员类型 map::mapped_type
Compare
一个二元值,它将两个元素的 Key 值作为输入参数,并返回一个布尔值。表达式 comp(a, b),其中 comp 是该类型的对象,a, b是 Key 值,如果按照函数定义的严格弱排序,参数 a 被认为排在参数 b 之前,则返回 true。
map 对象使用该表达式确定元素在容器中的位置,并判断两个元素的 Key 值是否相等(通过自反比较:如果 (!comp(a,b) && !comp(b,a) ) 结果为真,则 a, b 等价)。map 容器中没有两个元素拥有相同的 Key 值。
Compare 可以使一个函数指针,或者函数对象(详细请参阅示例构造函数)。默认值小于
<T>,返回应用小于运算符 (a < b) 相同的值;
别名为成员类型 map::key_compare
Alloc
用于定义存储分配模型的分配器对象的类型。默认情况下使用分配器类模板,它定义了最简单的模型分配模型,而且与值无关。
别名为成员类型 map::allocator_type
五、常用函数
构造函数在后续的程序示例中展示了五种不同的构造函数;
clear
清除 map 中所有元素;
erase
删除 map 中指定位置的元素;
insert
在 map 指定位置添加 pair 类型的元素;
find
获取 map 中元素的迭代器;
begin, end
map 的正向迭代器的起始位置与终点位置;
rbegin, rend
map 的反向迭代器的起始位置与终点位置;
六、程序示例
以下源码摘自《C++STL之map学习》,笔者对其进行注释。#include <iostream> #include <map> using namespace std; // 比较函数(用于后面的函数指针定义) bool fncomp(char lhs, char rhs){ return lhs < rhs; } // 定义一个 Compare 对象,且内部对运算符 () 进行重载 struct classcomp{ bool operator() (const char& lhs, const char& rhs){ return lhs < rhs; } }; int main(int argc, char* argv[]) { //========================= // map 的多种构造函数 //========================= // 1. 直接定义 map<char,int> mymap; mymap['a'] = 10; mymap['b'] = 60; mymap['c'] = 30; mymap['d'] = 90; mymap['e'] = 50; // 2. 复制 map<char, int> second(mymap); // 3. 通过迭代器 map<char, int> third(mymap.begin(),mymap.end()); // 4. 重新定义 Compare 对象,该对象内部对运算符 () 进行重载 map<char, int, classcomp> fourth; // 5. 通过函数指针 bool(*fn_pt)(char, char) = fncomp; map<char, int, bool(*)(char, char)> fifth(fn_pt); //========================= // 以最初定义的mymap 为例,讲解 map 的使用 //========================= map<char,int>::key_compare key_comp; map<char,int>::iterator it; it = mymap.begin(); //========================= // 1. 输出所有 Pair 元素 //========================= // 迭代器遍历 map for (it; it != mymap.end(); it++) { // map的迭代器,可以用 first 访问std::pair的第一个成员(Type1),second 访问第二个成员 (Type2) cout<<it->first<<":"<<it->second<<endl; } cout<<"================================="<<endl; //========================= // 2. 修改映射值 //========================= second.clear(); second['a']=1002; second['b']=10023; while (!second.empty()) { cout << second.begin()->first << " => "; cout << second.begin()->second << endl; second.erase(second.begin()); } cout<<"================================="<<endl; //========================= // 3. 插入 //========================= mymap.insert(pair<char,int>('f',100) ); mymap.insert(pair<char,int>('g',200) ); cout<<"f => " <<mymap.find('f')->second<<endl; cout<<"g => " <<mymap.find('g')->second<<endl; cout<<"================================="<<endl; //========================= // 4. Compare 参数的使用 //========================= key_comp = mymap.key_comp(); cout << "mymap contains:\n"; // 迭代器反向遍历的起始位置 char highest = mymap.rbegin()->first; // key value of last element it = mymap.begin(); do { cout << (*it).first << " => " << (*it).second << endl; } while ( key_comp((*it++).first, highest) ); cout << endl; return 0; }
运行结果如下:
相关文章推荐
- 【学习C++】Map使用
- C++ STL容器的学习使用(vector、queue、list、set、map)
- C++学习笔记——map与set的组合使用
- c++学习笔记-map的使用实例(单词转换)
- 菜鸟学习c++—map使用练习 实现词频统计程序
- 使用c++开发学习笔记
- c++ 学习使用 template
- [C++再学习系列] 避免使用宏
- 被误解的C++——学习和使用
- 智能指针auto_prt的使用(c++学习笔记)
- [学习笔记][C++Primer Plus]使用cout格式化输出字符串,3q xuzhong
- 使用doxygen从c++代码中生成文档的方法学习
- C++ map的使用
- C++ STL学习笔记十二 hash_map映照容器
- 词频统计的C++实现(使用stl--map)
- C++ 标准库 vector list map 基本使用方法 示例程序
- C++之父元旦专访(8+13个问题,关于C++的学习&使用和未来)
- C++/GDI+ 学习笔记(一)——安装、配置&使用
- Windows编程 C++ DLL编程 学习笔记(一)静态链接库的创建和使用
- 《被误解的C++——学习和使用》的案例