STL容器:map

stl,容器,map · 浏览次数 : 4

小编点评

```c++ #include <iostream>#include <map>#include <string>using namespace std;int main() { map<string, int> dict; //dict是一个string到int的映射,存放每个名字对应的班级号,初始时为空 dict[\"Tom\"] = 1; // {\"Tom\"->1} dict[\"Jone\"] = 2; // {\"Tom\"->1, \"Jone\"->2} dict[\"Mary\"] = 1; // {\"Tom\"->1, \"Jone\"->2, \"Mary\"->1} cout << \"Mary is in class \" << dict[\"Mary\"] << endl; cout << \"Tom is in class \" << dict[\"Tom\"] << endl; return 0;} ``` **运行结果:** ``` Mary is in class "Mary" Tom is in class "Tom" ``` **代码解释:** 1. **定义一个名为 `dict` 的映射**,其中键是字符串,值是整数。 2. **将一些值添加到 `dict` 中**,其中键和值都是字符串。 3. **使用 `for` 循环遍历 `dict`,并打印每个键和值的对。 4. **使用 `count` 函数检查 `dict` 中是否存在键 `"Mary"`**。 5. **如果 `Mary` 存在,则返回 `1`,表示她属于 `dict` 中的键。 6. **否则,返回 `0`,表示她没有属于 `dict` 中的键。

正文

 

map 可以当作特殊的数组来使用,在数组开不下,或者数组下标不是整数的时候使用 map 就很方便,比如统计字符串的出现个数,统计 int 范围内的数的出现次数等等。
映射是指两个集合之间的元素的相互对应关系。就是一个元素对应另外一个元素。
打个比方说有一个姓名的集合 { " T o m " , " J o n e " , " M a r y " } \{"Tom", "Jone", "Mary"\} {"Tom","Jone","Mary"},班级集合 { 1 , 2 } \{1,2\} {1,2}。姓名与班级之间可以有如下的映射关系: c l a s s ( " T o m " ) = 1 class("Tom")=1 class("Tom")=1 c l a s s ( " J o n e " ) = 2 class("Jone")=2 class("Jone")=2 c l a s s ( " M a r y " ) = 1 class("Mary") =1 class("Mary")=1

在这里插入图片描述
我们称其中的姓名集合为关键字集合(key),班级集合为值集合(value)。

构造一个 mapmap<T1, T2> m ;
定义了一个名为的从T1类型到T2类型的映射。
访问 map 的某一个位置和改变 map 某一个位置的数据的操作与数组一样,直接用 [] 就能访问或更改值了。
所以咱们也可以把 map 看成是一种特殊数组,下标可以不为整数的数组。

#include <iostream>
#include <map>
#include <string>
using namespace std;
int main() {
    map<string, int> dict;  
    //dict是一个string到int的映射,存放每个名字对应的班级号,初始时为空
    dict["Tom"] = 1;   
    // {"Tom"->1}
    dict["Jone"] = 2;  
    // {"Tom"->1, "Jone"->2}
    dict["Mary"] = 1;  
    // {"Tom"->1, "Jone"->2, "Mary"->1}
    cout << "Mary is in class " << dict["Mary"] << endl;
    cout << "Tom is in class " << dict["Tom"] << endl;
    return 0;
}

直接访问 map 中的一个位置,时间复杂度为 O ( l o g ⁡  n ) O(log⁡\ n) O(log n)

不过我们如果用刚才的方法访问 map 会有一个很神奇的事情。(啊先卖个关子…)
如果我们在访问 dict[Tom] 的时候,map 内部还没有 "Tom" 这个下标的话,系统会自动给 "Tom" 生成一个映射,其 value 为对应类型的默认值也就是它自动会完成(这里以string类型举例)dict[Tom] = "";
这句话。
但是我们一般都不需要系统这么做,我们想知道 "Tom" 这个 key 是否在 map 里存在;这时就可以借助 count 函数进行判断。
如果这个 key 存在会返回 1 1 1 ;否则会返回 0 0 0

#include <iostream>
#include <map>
#include <string>
using namespace std;
int main() {
    map<string, int> dict;  // {}
    dict["Tom"] = 1;        // {"Tom"->1}
    dict["Jone"] = 2;       // {"Tom"->1, "Jone"->2}
    dict["Mary"] = 1;       // {"Tom"->1, "Jone"->2, "Mary"->1}
    if (dict.count("Mary")) {
        cout << "Mary is in class " << dict["Mary"] << endl;
    } else {
        cout << "Mary has no class" << endl;
    }
    return 0;
}

map 的迭代器的定义和 set 差不多:map<T1, T2>::iterator it
这样就定义了一个迭代器,其中 T1 , T2 分别是 keyvalue 的类型。

C++通过迭代器可以访问集合中的每个元素。这里迭代器指向的元素是一个 pairpair 可以看作是一个有两个成员变量 firstsecond 的结构体,排序方法默认为先比较 firstfirst小的算小,first 一样就比较 secondsecond 小的算小。在 map 里每一个 pairfirstsecond 分别代表一个映射的 keyvalue

我们用->(捡大鱼 指向的)运算符来获取值,it->first(*it).first 的效果一样,就是获取迭代器 it 指向的 pairfirst 成员的值。

#include <iostream>
#include <map>
#include <string>
using namespace std;
int main() {
    map<string, int> dict;
    // {}
    dict["Tom"] = 1;
    // {"Tom"->1}
    dict["Jone"] = 2;
    // {"Tom"->1, "Jone"->2}
    dict["Mary"] = 1;
    // {"Tom"->1, "Jone"->2, "Mary"->1}
    for (map<string, int>::iterator it = dict.begin(); it != dict.end(); it++) {
        cout << it->first << " -> " << it->second << endl;
        // first 是关键字, second 是对应的值
    }
    return 0;
}

与STL容器:map相似的内容:

STL容器:map

map 可以当作特殊的数组来使用,在数组开不下,或者数组下标不是整数的时候使用 map 就很方便,比如统计字符串的出现个数,统计 int 范围内的数的出现次数等等。 映射是指两个集合之间的元素的相互对应关系。就是一个元素对应另外一个元素。 打个比方说有一个姓名的集合 { " T o m " , "

6.1 C++ STL 序列映射容器

Map/Multimap 映射容器属于关联容器,它的每个键对应着每个值,容器的数据结构同样采用红黑树进行管理,插入的键不允许重复,但值是可以重复的,如果使用`Multimap`声明映射容器,则同样可以插入相同的键值。Map中的所有元素都会根据元素的键值自动排序,所有的元素都是一个`Pair`同时拥有实值和键值,Pair的第一个元素被视为键值,第二个元素则被视为实值,Map 容器中不允许两个元素有相

C++ STL 容器简单讲解

STL 简单讲解 网上有很多很好的资料可以参考 而直接看标准是最准确清晰的 vector stack queue / priority_queue deque array map / multimap set / multiset unordered_map unordered_set 关于指针和迭

11.1 C++ STL 应用字典与列表

C++ STL 标准模板库提供了丰富的容器和算法,这些模板可以灵活组合使用,以满足不同场景下的需求。本章内容将对前面学习的知识进行总结,并重点讲解如何灵活使用STL中的vector和map容器,以及如何结合不同的算法进行组合。通过灵活组合使用这些容器和算法,能够满足不同场景下的需求,实现高效的数据处理和操作。STL的设计思想是将数据结构和算法进行分离,使得开发者能够更加专注于解决问题,提高了代码的

10.1 C++ STL 模板适配与迭代器

STL(Standard Template Library)标准模板库提供了模板适配器和迭代器等重要概念,为开发者提供了高效、灵活和方便的编程工具。模板适配器是指一组模板类或函数,它们提供一种适配机制,使得现有的模板能够适应新的需求。而迭代器则是STL中的令一种重要的概念,它是一个抽象化的数据访问机制,通过迭代器可以遍历STL容器中的元素。适配器与迭代器两者的紧密配合,使得开发者能够高效地处理容器

2.1 C++ STL 数组向量容器

Vector容器是C++ STL中的一个动态数组容器,可以在运行时动态地增加或减少其大小,存储相同数据类型的元素,提供了快速的随机访问和在末尾插入或删除元素的功能。该容器可以方便、灵活地代替数组,容器可以实现动态对数组扩容删除等各种复杂操作,其时间复杂度`O(l)常数阶`,其他元素的插入和删除为`O(n)线性阶`,其中n为容器的元素个数,vector具有自动的内存管理机制,对于元素的插入和删除可动

3.1 C++ STL 双向队列容器

双向队列容器(Deque)是C++ STL中的一种数据结构,是一种双端队列,允许在容器的两端进行快速插入和删除操作,可以看作是一种动态数组的扩展,支持随机访问,同时提供了高效的在队列头尾插入和删除元素的操作。Deque 双向队列容器与Vector非常相似,它不但可以在数组尾部插入和删除元素,还可以在头部进行插入和删除,队列算法的时间复杂度也是`常数阶O(1)`,队列内部的数据机制和性能与Vecto

4.1 C++ STL 动态链表容器

List和SList都是C++ STL中的容器,都是基于双向链表实现的,可以存储可重复元素的特点。其中,List内部的节点结构包含两个指针一个指向前一个节点,一个指向后一个节点,而SList只有一个指针指向后一个节点,因此相对来说更节省存储空间,但不支持反向遍历,同时也没有List的排序功能。双向链表的数据元素可以通过链表指针串接成逻辑意义上的线性表,不同于采用线性表顺序存储结构的`Vector`

5.1 C++ STL 集合数据容器

Set/Multiset 集合使用的是红黑树的平衡二叉检索树的数据结构,来组织泛化的元素数据,通常来说红黑树根节点每次只能衍生出两个子节点,左面的节点是小于根节点的数据集合,右面的节点是大于根节点的集合,通过这样的方式将数据组织成一颗看似像树一样的结构,而平衡一词的含义则是两边的子节点数量必须在小于等1的区间以内。Set集合天生去重,所有元素都会根据元素的键值自动的排序,并且Set元素在确定后无法

1.1 C++ STL 字符串构造函数

String 字符串操作容器是C++标准中实现的重要容器,其主要用于对字符串的高效处理,它和C风格中的`string.h`并不是同一个库,两个库有极大的差距,C库中的`string.h`主要面向过程提供一些处理函数,而C++库中的`string`则是基于类实现的更高效的一种字符串处理方法集,类中提供了非常方便的成员函数供我们使用.