数据结构map的基本知识与用法

这篇具有很好参考价值的文章主要介绍了数据结构map的基本知识与用法。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

map

1 介绍

映射类似于函数的对应关系,每个x对应一个y,而map是每个键对应一个值。会python的朋友学习后就会知道这和python的字典非常类似。

比如说:学习 对应 看书,学习 是键,看书 是值。
学习->看书
玩耍 对应 打游戏,玩耍 是键,打游戏 是值。
玩耍->打游戏

        

Cpp

map特性:map会按照键的顺序从小到大自动排序,键的类型必须可以比较大小

2 函数方法

2.1 函数方法

代码 含义
mp.find(key ) 返回键为key的映射的迭代器 O(logN)  注意:用find函数来定位数据出现位置,它返回一个迭代器。当数据存在时,返回数据所在位置的迭代器,数据不存在时,返回mp.end()
mp.erase(it)               删除迭代器        的键和值O(1)
mp.erase(key) 根据映射的键删除键和值 O(logN)
mp.erase(first,last) 删除左闭右开区间迭代器对应的键和值O(last−first)
mp.size() 返回映射的对数$ O(1)$
mp.clear() 清空map中的所有元素O(N)
mp.insert() 插入元素,插入时要构造键值对
mp.empty() 如果map为空,返回true,否则返回false
mp.begin() 返回指向map第一个元素的迭代器(地址)
mp.end() 返回指向map尾部的迭代器(最后一个元素的下一个地址)
mp.rbegin() 返回指向map最后一个元素的迭代器(地址)
mp.rend() 返回指向map第一个元素前面(上一个)的逆向迭代器(地址)
mp.count(key) 查看元素是否存在,因为map中键是唯一的,所以存在返回1,不存在返回0
mp.lower_bound() 返回一个迭代器,指向键值>= key的第一个元素
mp.upper_bound() 返回一个迭代器,指向键值> key的第一个元素

2.2 注意点

下面说明部分函数方法的注意点

注意:
查找元素是否存在时,可以使用
mp.find() ② mp.count() ③ mp[key]
但是第三种情况,如果不存在对应的key时,会自动创建一个键值对(产生一个额外的键值对空间)
所以为了不增加额外的空间负担,最好使用前两种方法

2.3 迭代器进行正反向遍历

  • mp.begin()mp.end()用法:

用于正向遍历map

map<int,int> mp;
mp[1] = 2;
mp[2] = 3;
mp[3] = 4;
auto it = mp.begin();
while(it != mp.end()) {
	cout << it->first << " " << it->second << "\n";
	it ++;
}

Cpp

结果:

1 2
2 3
3 4

None

  • mp.rbegin()mp.rend()

用于逆向遍历map

map<int,int> mp;
mp[1] = 2;
mp[2] = 3;
mp[3] = 4;
auto it = mp.rbegin();
while(it != mp.rend()) {
	cout << it->first << " " << it->second << "\n";
	it ++;
}

Cpp

结果:

3 4
2 3
1 2

None

2.4 二分查找

二分查找lower_bound() upper_bound()

map的二分查找以第一个元素(即键为准),对进行二分查找
返回值为map迭代器类型

#include<bits/stdc++.h>
using namespace std;

int main() {
	map<int, int> m{{1, 2}, {2, 2}, {1, 2}, {8, 2}, {6, 2}};//有序
	map<int, int>::iterator it1 = m.lower_bound(2);
	cout << it1->first << "\n";//it1->first=2
	map<int, int>::iterator it2 = m.upper_bound(2);
	cout << it2->first << "\n";//it2->first=6
	return 0;
}

Cpp

3 添加元素

//先声明
map<string, string> mp;

Cpp

  • 方式一:
mp["学习"] = "看书";
mp["玩耍"] = "打游戏";

Cpp

  • 方式二:插入元素构造键值对
mp.insert(make_pair("vegetable","蔬菜"));

Cpp

  • 方式三:
mp.insert(pair<string,string>("fruit","水果"));

Cpp

  • 方式四:
mp.insert({"hahaha","wawawa"});

Cpp

4 访问元素

4.1 下标访问

(大部分情况用于访问单个元素)

mp["菜哇菜"] = "强哇强";
cout << mp["菜哇菜"] << "\n";//只是简写的一个例子,程序并不完整

Cpp

4.2 遍历访问

  • 方式一:迭代器访问
map<string,string>::iterator it;
for(it = mp.begin(); it != mp.end(); it++) {
	//      键                 值 
	// it是结构体指针访问所以要用 -> 访问
	cout << it->first << " " << it->second << "\n";
	//*it是结构体变量 访问要用 . 访问
	//cout<<(*it).first<<" "<<(*it).second;
}

Cpp

  • 方式二:智能指针访问
for(auto i : mp)
cout << i.first << " " << i.second << endl;//键,值

Cpp

  • 方式三:对指定单个元素访问
map<char,int>::iterator it = mp.find('a');
cout << it -> first << " " <<  it->second << "\n";

Cpp

  • 方式四:c++17特性才具有
for(auto [x, y] : mp)
	cout << x << " " << y << "\n";
//x,y对应键和值

Cpp

5 与unordered_map的比较

这里就不单开一个大目录讲unordered_map了,直接在map里面讲了。

5.1 内部实现原理

map:内部用红黑树实现,具有自动排序(按键从小到大)功能。

unordered_map:内部用哈希表实现,内部元素无序杂乱。

5.2 效率比较

map

  • 优点:内部用红黑树实现,内部元素具有有序性,查询删除等操作复杂度为O(logN)

  • 缺点:占用空间,红黑树里每个节点需要保存父子节点和红黑性质等信息,空间占用较大。

unordered_map

  • 优点:内部用哈希表实现,查找速度非常快(适用于大量的查询操作)。
  • 缺点:建立哈希表比较耗时。

两者方法函数基本一样,差别不大。

注意:

  • 随着内部元素越来越多,两种容器的插入删除查询操作的时间都会逐渐变大,效率逐渐变低。

  • 使用[]查找元素时,如果元素不存在,两种容器都是创建一个空的元素;如果存在,会正常索引对应的值。所以如果查询过多的不存在的元素值,容器内部会创建大量的空的键值对,后续查询创建删除效率会大大降低

  • 查询容器内部元素的最优方法是:先判断存在与否,再索引对应值(适用于这两种容器)

    // 以 map 为例
    map<int, int> mp;
    int x = 999999999;
    if(mp.count(x)) // 此处判断是否存在x这个键
        cout << mp[x] << "\n";   // 只有存在才会索引对应的值,避免不存在x时多余空元素的创建

    Cpp

另外:

还有一种映射:multimap

键可以重复,即一个键对应多个值,如要了解,可以自行搜索

例题

P5266 【深基17.例6】学籍管理 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)

要设计一个学籍管理系统,最开始学籍数据是空的,然后该系统能够支持下面的操作(不超过 105105 条):

  • 插入与修改,格式1 NAME SCORE:在系统中插入姓名为 NAME(由字母和数字组成不超过 20 个字符的字符串,区分大小写) ,分数为 SCORESCORE(0<SCORE<2310<SCORE<231) 的学生。如果已经有同名的学生则更新这名学生的成绩为 SCORE。如果成功插入或者修改则输出OK
  • 查询,格式2 NAME:在系统中查询姓名为 NAME 的学生的成绩。如果没能找到这名学生则输出Not found,否则输出该生成绩。
  • 删除,格式3 NAME:在系统中删除姓名为 NAME 的学生信息。如果没能找到这名学生则输出Not found,否则输出Deleted successfully
  • 汇总,格式4:输出系统中学生数量。

输入格式

输出格式

输入输出样例

输入 #1

5
1 lxl 10
2 lxl
3 lxl
2 lxl
4

输出 #1文章来源地址https://www.toymoban.com/news/detail-828024.html

OK
10
Deleted successfully
Not found
0

解决代码

#include <iostream>
#include <map>
#include <string>
using namespace std;
int main() {
    map<string, long long> a;
    int key, i = 1;
    cin >> i;
   string name;
   long long score;
    while (i--) {
        cin >> key;
        switch (key) {
            case 1:                
                cin >> name >> score;
                a[name] = score;
                cout << "OK" << endl;
                break;
            case 2:
                cin >> name;
                if (a.count(name)) {
                    cout << a[name] << endl;
                } else {
                    cout << "Not found" << endl;
                }
                break;
            case 3:
                cin >> name;
                if (a.find(name) != a.end()) {
                    a.erase(name);
                    cout << "Deleted successfully" << endl;
                } else {
                    cout << "Not found" << endl;
                }
                break;
            case 4:
                cout << a.size() << endl;
                break;
        }
    }

    return 0;
}

到了这里,关于数据结构map的基本知识与用法的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包赞助服务器费用

相关文章

  • 音频数据处理基本知识学习——降噪滤波基础知识

    滤波是一种信号处理方法,它可以通过消除或减弱信号中的某些频率分量,来实现信号的去噪、去除干扰、增强某些频率成分等目的。常见的滤波方法包括低通滤波、高通滤波、带通滤波等。 降噪是一种信号处理方法,它可以通过消除或减弱信号中的噪声成分,来提高信号的

    2024年02月15日
    浏览(20)
  • 【树结构从入门到应用】树的基本知识,树的遍历算法,树结构的应用-电话薄管理与文件系统操作,示例+代码

    目录 1 树的定义 2 树的基本术语 3 树的示例 4 常见的树类型  5 树的遍历算法与代码示例  5.1  前序遍历(Preorder Traversal) 5.2  中序遍历(Inorder Traversal) 5.3 后序遍历(Postorder Traversal)  5.4 代码示例        6 树结构应用示例 6.1 二叉搜索树(Binary Search Tree)管理电话簿 6

    2024年02月07日
    浏览(44)
  • 【MySQL】数据库基本知识小结

    【MySQL】数据库基本知识小结

    哈喽大家好,我是阿Q,今天我们来总结一下【MySQL】 入门的必备知识点吧~ 数据库 :DataBase 简称 DB,就是信息的集合或者说数据库是由数据库管理系统管理的数据的集合。 数据库管理系统 :DataBase Management System 简称 DBMS,是一种操纵和管理数据库的大型软件,通常用于建立

    2024年02月09日
    浏览(17)
  • 数据库的基本知识---入门前必读

    数据库的基本知识---入门前必读

    目录 一.认识数据库 二.数据库的分类 三.SQL介绍 3.1SQL是什么 3.2.SQL语言使用方式 总结 😽个人主页:tq02的博客_CSDN博客-C语言,Java,Java数据结构领域博主  🌈梦的目标:努力学习,打败数据库,拼搏一切,让自己的未来不会有遗憾。  🎁欢迎各位→ 点赞 👍 + 收藏 ⭐ + 评论

    2024年02月09日
    浏览(24)
  • ES6基础知识五:你是怎么理解ES6新增Set、Map两种数据结构的?

    ES6基础知识五:你是怎么理解ES6新增Set、Map两种数据结构的?

    如果要用一句来描述,我们可以说 Set是一种叫做集合的数据结构,Map是一种叫做字典的数据结构 什么是集合?什么又是字典? 集合 是由一堆无序的、相关联的,且不重复的内存结构【数学中称为元素】组成的组合 字典 是一些元素的集合。每个元素有一个称作key 的域,不同

    2024年02月16日
    浏览(11)
  • 深度学习基础知识-pytorch数据基本操作

    深度学习基础知识-pytorch数据基本操作

    1.1.1 数据结构 机器学习和神经网络的主要数据结构,例如                 0维:叫标量,代表一个类别,如1.0                 1维:代表一个特征向量。如  [1.0,2,7,3.4]                 2维:就是矩阵,一个样本-特征矩阵,如: [[1.0,2,7,3.4 ]                   

    2024年02月11日
    浏览(10)
  • HBase基础知识(一):HBase简介、HBase数据模型与基本架构

    HBase基础知识(一):HBase简介、HBase数据模型与基本架构

    HBase是一种分布式、可扩展、支持海量数据存储的NoSQL数据库。 逻辑上,HBase的数据模型同关系型数据库很类似,数据存储在一张表中,有行有列。但从HBase的底层物理存储结构(K-V)来看,HBase更像是一个 multi-dimensionalmap 。 1.2.1HBase逻辑结构 字典序:按位比较。 下图是一张表

    2024年02月03日
    浏览(12)
  • 【MySQL数据库重点】第二节:MySQL基础知识(基本操作)

    目录 一:数据库的操作 1.显示数据库 2.创建数据库 3.使用数据库 4.删除数据库 二:常用数据类型 1.数值类型:整型和浮点型 2.字符串类型 3.日期类型 三:表的操作 1.查看表结构 2.创建表 3.删除表 1.显示数据库 语法: show databases;  2.创建数据库 (1)简化语法 create database 数

    2024年02月08日
    浏览(15)
  • 【postgresql 基础入门】数据表的查询基本知识,条件过滤、单列多列排序、按页浏览数据、数据去重,得到你想要的数据

    ​ 专栏内容 : postgresql内核源码分析 手写数据库toadb 并发编程 ​ 开源贡献 : toadb开源库 个人主页 :我的主页 管理社区 :开源数据库 座右铭:天行健,君子以自强不息;地势坤,君子以厚德载物. 入门准备 postgrersql基础架构 快速使用 初始化集群 数据库服务管理 psql客户

    2024年02月07日
    浏览(60)
  • Java面试题:解释Java的基本数据类型及其大小和默认值,列举数据类型常见的错误知识点

    Java的基本数据类型是Java编程语言中用于存储简单值的类型。这些数据类型包括整数类型、浮点类型、字符类型和布尔类型。下面是对这些基本数据类型的详细解释,包括它们的大小和默认值,以及一些常见的面试中容易出错的知识点。 基本数据类型及其大小和默认值 整型

    2024年04月16日
    浏览(17)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包