赞
踩
本文主要介绍C++编程语言的STL(Standard Template Library)中map容器及相关容器的相关知识,同时通过示例代码介绍这些容器的常见用法。
关联容器(associative-container)和顺序容器有着根本的不同:关联容器中的元素是按关键字来保存和访问的,而顺序容器中的元素是按它们在容器中的位置来顺序保存和访问的。
虽然关联容器的很多行为与顺序容器相同,但其不同之处反映了关键字的作用。关联容器支持高效的关键字查找和访问。
两个主要的关联容器类型为map和set。map中的元素是一些“关键字-值对(key-value)”:“关键字”起索引的作用,“值”则表示与索引相关联的数据。set中每个元素只包含一个关键字。
map的特性如下:
构造map的方法如下(以键值对为“int-string”类型为例):
map<int, string> mapStudent;
map提供了几种插入元素的方法。
使用insert函数插入pair数据:
- mapStudent.insert(pair<int, string>(1, "zhao"));
- mapStudent.insert(pair<int, string>(2, "qian"));
- mapStudent.insert(pair<int, string>(3, "sun"));
使用数组方式插入数据:
- mapStudent[1] = "zhao";
- mapStudent[2] = "qian";
- mapStudent[3] = "sun";
说明:上面的两种方法是有区别的,用insert函数插入数据,涉及到集合的唯一性的概念,即当map中有这个关键字时,insert操作是不能实现数据插入的;但是数组方式能够插入数据,插入的数据会覆盖该关键字之前对应的值。
可以通过map的迭代器iterator、调用map对象的begin()和end()函数,实现对于map中数据的遍历操作,示例代码如下:
- // 遍历
- cout << "content of map as followed: " << endl;
- mapStudent_t::iterator iter;
- for (iter = mapStudent.begin(); iter != mapStudent.end(); iter++)
- {
- cout << iter->first << " " << iter->second << endl;
- }
说明:
1)begin()和end()两个成员函数,分别对应map对象中第一个和最后一个数据条目,这两个数据条目的类型是iterator;
2)通过map对象的方法获取到的iterator数据类型是一个“std::pair”对象,iterator数据类型包括下面两个数据:
可以通过使用map的迭代器iterator、调用find函数(传入的参数为要查找的key),来查找具体的元素,示例代码如下:
- // 查找
- iter = mapStudent.find(2);
- if (iter != mapStudent.end())
- {
- cout << "Find it, the relative value is: " << iter->second << endl;
- }
- else
- {
- cout << "Can not find the relative value." << endl;
- }
说明:find函数的入参为map的key,并且入参必须完全匹配map的key,才能找到对应元素的value。例如,对于以下map结构:
mapStudent.insert(pair<string, string>("zhao", "zhaoyun"));
如果要查找该map中的元素,必须在find函数中输入完整的key(即“zhao”)才行,如果输入的入参为“zh”、或“zha”,都不能找到该元素。
对于map中的数据删除操作,分为以下两种情况:
1)如果想要清空map中的所有数据,可以使用clear函数;
2)如果想要删除map中的指定数据,可以通过使用map的迭代器iterator、调用erase函数来实现,示例代码如下:
- // 删除
- iter = mapStudent.find(3);
- mapStudent.erase(iter);
此处展示一个输出map结构内容的示例代码。代码(map_test1.cpp)内容如下:
- #include <iostream>
- #include <map>
-
- using namespace std;
-
- int main()
- {
- // <int, string>结构的map
- typedef std::map<int, string> mapStudent_t;
- mapStudent_t mapStudent;
-
- mapStudent.insert(pair<int, string>(1, "zhao"));
- mapStudent.insert(pair<int, string>(2, "qian"));
- mapStudent.insert(pair<int, string>(3, "sun"));
-
- // map简单的输出方法
- cout << "mapStudent[1] is: " << mapStudent[1] << endl;
- cout << "mapStudent[3] is: " << mapStudent[3] << endl;
-
- // <string, string>结构的map
- typedef std::map<string, string> mapRole_t;
- mapRole_t mapRole;
-
- mapRole.insert(pair<string, string>("mage", "alliance"));
- mapRole.insert(pair<string, string>("paladin", "alliance"));
- mapRole.insert(pair<string, string>("warlock", "Horde"));
-
- // map简单的输出方法
- cout << "mapRole[\"mage\"] is: " << mapRole["mage"] << endl;
- cout << "mapRole[\"warlock\"] is: " << mapRole["warlock"] << endl;
-
- return 0;
- }
-
编译并执行上述代码,结果如下:
示例代码(map_test2.cpp)内容如下:
- #include <iostream>
- #include <map>
- #include <string>
-
- using namespace std;
-
- int main()
- {
- typedef std::map<int, string> mapStudent_t;
- mapStudent_t mapStudent;
-
- mapStudent.insert(pair<int, string>(1, "zhao"));
- mapStudent.insert(pair<int, string>(2, "qian"));
- mapStudent.insert(pair<int, string>(3, "sun"));
-
- // 遍历
- cout << "content of map as followed: " << endl;
- mapStudent_t::iterator iter;
- for (iter = mapStudent.begin(); iter != mapStudent.end(); iter++)
- {
- cout << iter->first << " " << iter->second << endl;
- }
-
- // 查找
- iter = mapStudent.find(2);
- if (iter != mapStudent.end())
- {
- cout << "Find it, the relative value is: " << iter->second << endl;
- }
- else
- {
- cout << "Can not find the relative value." << endl;
- }
-
- // 删除
- iter = mapStudent.find(3);
- mapStudent.erase(iter);
-
- // 再次遍历,观察删除操作是否成功
- cout << "after delete, content of map as followed: " << endl;
- for (iter = mapStudent.begin(); iter != mapStudent.end(); iter++)
- {
- cout << iter->first << " " << iter->second << endl;
- }
-
- return 0;
- }
上述代码运行结果如下:
C++标准库提供了四个无序关联容器(unordered associated container),这些容器不是使用比较运算符,而是使用一个哈希函数(hash function)和关键字类型的“==”运算符来组织元素。
在关键字类型的元素没有明显的“序关系”的情况下,无序容器是非常有用的。在某些应用中,维护元素的序的代价非常高昂,此时无序容器也很有用。
unordered_map就是C++标准库提供的四个无序关联容器之一。
unordered_map的特性如下:
构造unordered_map的方法如下(以key和value均为char类型为例):
unordered_map<char, char> unoMap;
可以通过[]运算符来执行插入元素操作,示例代码如下:
unoMap['a'] = 'b';
说明:如果key对应的value存在,则执行更新元素操作,否则执行添加元素操作。
可以通过使用unordered_map的迭代器iterator、调用find函数(传入的参数为要查找的key),来查找具体的元素,示例代码如下:
- // 查找
- if (mapStudent.find(2) != mapStudent.end())
- {
- ...
- }
此外,也可以通过[]运算符来执行查找元素操作,示例代码如下:
char chValue = unoMap['a'];
利用unordered_map计算字符串中各个字符出现的次数,示例代码如下:
- string strDemo = "aabcccc";
- unordered_map<char, int> unoMap;
- for (auto ch:strDemo) {
- // unoMap[ch]即为ch字符对应的出现次数
- unoMap[ch]++;
- }
查询某元素在unordered_map中出现的次数,方法如下(返回0或1):
m.count(i)
STL默认提供的map是“有序”的(即“map”),同时也提供了对应的“无序”版本(即“unordered_map”)。
对于map容器来说,存储于其中的元素是否有序,只会在使用迭代器iterator等场景下对我们有影响,而当我们使用“key-value”获取元素内容时,容器是否有序是无影响的。
下面给出一个简单的示例代码:
- #include <map>
- #include <unordered_map>
- #include <iostream>
-
- using namespace std;
-
- int main()
- {
- map<int, char> Map;
- Map[1] = 'a';
- Map[2] = 'b';
- Map[3] = 'c';
- Map[4] = 'd';
- Map[5] = 'e';
-
- cout << "the Map output is: " << endl;
- for (auto i = Map.begin(); i != Map.end(); i++) {
- std::cout << i->first << ' ' << i->second << std::endl;
- }
- cout << "Map[2] is: " << Map[2] << endl;
-
- unordered_map<int, char> unoMap;
- unoMap[1] = 'a';
- unoMap[2] = 'b';
- unoMap[3] = 'c';
- unoMap[4] = 'd';
- unoMap[5] = 'e';
-
- cout << "the unordered_map output is: " << endl;
- for (auto i = unoMap.begin(); i != unoMap.end(); i++) {
- std::cout << i->first << ' ' << i->second << std::endl;
- }
- cout << "unoMap[2] is: " << unoMap[2] << endl;
-
- return 0;
- }
上方代码的运行结果如下:
从上述代码运行结果可以看出:
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。