C++中map字典怎么用

发布时间:2021-09-15 15:02:14 作者:小新
来源:亿速云 阅读:180

这篇文章主要介绍了C++中map字典怎么用,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。

1、map 类型的声明

若想在 C++ 中使用 map 类型创建字典,则需要包含 map 头文件,如下:

#include <map>

map 类型的定义如下:

map<KeyType, ValueType> dict;

其中,KeyType 代表键的数据类型,ValueType 代表值的数据类型。KeyType 默认是 const 类型,即键在确认之后为只读数据。另外,在一个 map 数据中,一个键只能出现一次;而在 multimap 类型数据中,一个键可以出现多次,本次主要讨论 map 数据。看下面一个例子:

#include <iostream>
#include <string>
#include <map>
 
using namespace std;
int main(void)
{
    map<string, int> dict{{"key1", 2}};  // 定义一个 map 类型数据 
    dict["key2"] = 3;  // 创建并赋值
    dict["key3"] ;
    cout << "length of dict: " << dict.size() << endl;  // 长度
    cout << dict["key1"] << endl;  // 查找
    cout << dict["key2"] << endl;
    cout << dict["key3"] << endl;  // 值默认为0 
}
 
//======= 运行结果如下 ========//
length of dict: 2
2
3
0

例子中首先声明了一个 map 类型数据 dict ,key 的数据类型为 string ,value 的数据类型为 int。初始化时注意一对键值对要放在一对花括号{}中,并用逗号隔开:

{key, value}

如果键 key 对还未出现在 dict 中,下标运算会创建一个新元素,其值默认为 0 。这里创建了三个键值对,一个key 为 字符串 "key1" ,值为 2;key 为 字符串 "key3" 的键值对由于未被赋值,因此其值默认为 0 。

2、pair 类型

上述 dict 字典中存储的每一个数据都是 pair 类型的数据,即 map 数据是一群 pair 类型的集合。一个 pair 保存两数据成员: first 和 second,分别用来存储一个键值对的 键 和 值 ,其中 first 成员是 const 的,这也解释了上面提到的 键在确认之后为只读数据。pair 的标准库类型定义在头文件 utility 中,在定义一个 pair 时,其默认构造函数会对数据成员进行初始化。一个例子如下:

int main(void)
{
    pair<string, int> a_pair{"key", 1};  // 定义一个 pair 并初始化
    cout << a_pair.first << ": " << a_pair.second << endl;
}
 
// =========== 运行结果 =========== //
key: 1

3、map 数据的遍历

map 数据的遍历主要有两种方法,一个是直接遍历,另一种是使用迭代器的遍历。

1)直接遍历:

#include <iostream>
#include <string>
#include <map>
 
using namespace std;
int main(void)
{
    map<string, int> dict;  // 定义一个 map 类型数据
    dict["key1"] = 2;  // 创建并赋值
    dict["key2"] = 3;  // 
    dict["key3"] ;     // 默认值为0
    for(auto c : dict)  // 遍历,c++11 特有循环方式
    {
        cout << c.first << ": " << c.second << endl;
    }
}
//============ 运行结果 ============//
key1: 2
key2: 3
key3: 0

这种遍历方式就是 for 循环直接遍历。每次循环都会从 dict 中提取一个 pair 类型的对象存入 c 中以供后续操作。

2)使用迭代器遍历

map 支持 vector 中的 begin、end、cbegin、cend 操作,因此我们可以使用这些函数获取迭代器,然后使用迭代器来遍历 map。begin、end 指向首元素以及尾元素之后位置(one past the last element)的迭代器,而容器中的元素位于 begin 与 end 之间,不包含 end,即是一个左闭右开的区间:[begin,end)。cbegin、cend 是C++11引入的新标准,返回 const_iterator,只能用来读取迭代器所指向内容的数据,不能修改数据 。一个使用迭代器遍历的例子如下:

#include <iostream>
#include <string>
#include <map>
 
using namespace std;
 
int main(void)
{   
    // 定义并初始化一个 map 类型数据 
    map<string, int> dict{{"key1", 1}, {"key2", 2}, {"key3", 3}};  
    auto map_it = dict.begin();  // 获取指向首元素的迭代器
    // 判断范围,比较当前迭代器和尾后元素迭代器
    while (map_it != dict.end())
    {
        cout << map_it->first << ": " << map_it->second << endl;
        map_it++;  // 迭代器递增,移动到下一个元素
    }
}

4、添加元素

map 的 insert 成员函数用来添加一个元素或者一个元素范围,emplace 成员函数用来添加单个元素。使用 insert 方法向 map 中添加元素的方法如下,不过常用的方式就是第一种方式,剩下的仨了解下就行。

dict.insert({"key", 1})    // 或者 dict.emplace({"key", 1})
dict.insert(make_pair("key", 1))
dict.insert(pair<string, int>("key", 1))
dict.insert(map<string, int>::value_type("key", 1))

另外对于一个不存在的键的单一元素的 insert 或者 emplace 的插入操作会返回一个 pair ,告诉我们是否添加成功,该 pair 的 first 成员是一个迭代器,指向具有给定关键字的元素,second 成员是一个 bool 值,指出元素是插入成功还是已存在于 dict 中,如果之前不存在,则返回true;如果先前已存在,则值为 false。

int main(void)
{
    map<string, int> dict{{"key1", 1}};  // 定义一个 map
    auto ret1 = dict.insert({"key2", 1}); // 执行插入操作,若 "key"不存在于dict中,则返回
    cout << "attention: ret1.first is a iterator points the element we insert" << endl;
    cout << ret1.first->first << ":" << ret1.first->second << endl;
    cout << "key2 insert successfully? " << ret1.second << endl;
    auto ret2 = dict.insert({"key1", 3}); //  "key"已存在于dict中,则insert什么也不做
    cout << "attention: ret2.first is a iterator points the element we insert" << endl;
    cout << ret2.first->first << ":" << ret2.first->second << endl;
    cout << "key1 insert successfully? " << ret2.second << endl;
}
//========= 运行结果 ==========//
attention: ret1.first is a iterator points the element we insert
key2:1
key2 insert successfully? 1
attention: ret2.first is a iterator points the element we insert
key1:1
key1 insert successfully? 0

例子中的返回值 pair 的完整类型如下:

pair<map<string, int>::iterator, bool>

但是!上面的 insert 方式还是麻烦了点,不如直接使用文章开头说的下标操作!如果键 key 对还未出现在 dict 中,下标运算会创建一个新元素,其值默认为 0 。

当插入一个元素范围时,可以做如下操作,这时没有返回值。

dict.insert(dict2.begin(), dict2.end());

5、删除元素

map 有三个版本的 erase 操作,分别如下:

1、dict.erase(key)

从 dict 中删除 键 为 key 的元素,返回删除元素的数量,对于 map 类型来说为 1。

2、dict.erase(p)

从 dict 中删除迭代器 p 指定的元素。p 必须指向 dict 中一个真实元素且不能等于 dict.end()。返回一个指向 p 之后的元素的迭代器。

3、dict.erase(b, e)

从 dict 中删除迭代器 b 和 e 之间的元素,返回e。

int main(void)
{
    // 定义并初始化一个 map 类型数据 
    map<string, int> dict{{"key1", 1}, {"key2", 2}, {"key3", 3}, {"key4", 4}, {"key5", 5}};  
    int ret1 = dict.erase("key1");  // 删除键为 "key1" 的元素
    cout << "ret1: " << ret1 << endl;
    auto ret2 = dict.erase(dict.begin());  // 使用迭代器
    cout << "(ret2->first:ret2->second) = " << ret2->first << ":" << ret2->second << endl;
    auto ret3 = dict.erase(dict.begin(), dict.end());  // 清空
    cout << "ret3->first: " << ret3->first << endl;
}
//=========== 运行结果 ============//
ret1: 1
(ret2->first:ret2->second) = key3:3
ret3->first:

6、访问元素

map 提供了一些查找元素的操作如下:

1、dict.find(key)
// 返回一个迭代器 ,指向第一个键为 key 的元素,若 key 不存在于 dict 中,则返回 dict.end()
2、dict.count(key)
// 返回键为 key 的元素的数量,对于 map 来说,返回1
3、dict.lower_bound(key)
// 返回一个迭代器,指向第一个键不小于 key 的元素
4、dict.upper_bound(key)
// 返回一个迭代器,指向第一个键大于 key 的元素
5、dict.equal_range(key)
// 返回一个迭代器pair,表示关键字恩于 key 的元素的范围。如果不存在,则pair的两个成员均为
//dict.end()

一般来说,2~5的方法多用于 multimap 类型的数据中。如果只是想查询一个元素是否存在于 dict 中,则使用 find 是最好的选择。

另外需要注意的是,如果使用下标操作访问元素,如果该元素并不存在于 dict 中,则该操作会创建一个元素,因此,使用什么样的访问方式需要根据我们的使用环境进行选择。

7、其他细节

map 是基于树的结构的,并且内部元素是有序的,即是经过键排序的:如果键的类型是数字,则按照数字大小进行排序,如果是 string,则按照字典序进行排序。

感谢你能够认真阅读完这篇文章,希望小编分享的“C++中map字典怎么用”这篇文章对大家有帮助,同时也希望大家多多支持亿速云,关注亿速云行业资讯频道,更多相关知识等着你来学习!

推荐阅读:
  1. STL中map怎么用
  2. C++中的map用法详解

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

c++ map

上一篇:TypeScript中如何使用interface和type

下一篇:如何使css浏览器下的背景色渐变

相关阅读

您好,登录后才能下订单哦!

密码登录
登录注册
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》