8、STL中的map和pair使用方法

news/2025/3/21 0:53:26/

一、了解

map提供了 key-value(键值对)的存储机制,这使得map成为处理具有唯一键的关联数据的理想选择。无重复值且有序

  • map特性
    • 键值对存储:每个键都有一个值对应。
    • 自动排序:map内部是平衡二叉搜索树(一般用红黑树)。可以自动排序
    • 元素具有唯一性:key对应唯一value
    • 直接访问:用键key来访问值
    • 灵活操作:有许多方便的操作
  • map的时间复杂度
    • 插入操作O(log n),其中n是std::map中元素的数量。这是因为需要在平衡二叉树中找到合适的位置来插入新元素。
    • 删除操作:删除操作的时间复杂度同样为O(log n),需要找到要删除的元素并在保持树平衡的同时移除它。
    • 查找操作:查找操作的时间复杂度也是O(log n),由于std::map的有序性,可以快速定位到任何键。
    • 遍历操作:遍历std::map的时间复杂度为O(n),因为需要访问容器中的每个元素。
  • 使用map所需要的头文件
#include <map>

二、初始化

1、pair的使用

  • pair头文件
它的头文件是 
#include< utility>

1.1、构造pair

  • 构造pair<Type1 , Type2 >
    • 记住make_pair的使用,这个经常用。
int main(int argv,char* argc[]){pair<string ,int>p1;pair<string ,int>p2=p1;pair<string ,int>p3(p2);pair<string ,int>p4={"1",1};pair<string ,int>p5=make_pair("1",1);
}

1.2、访问pair

  • first(): 访问第一个
  • second(): 访问第二个
int main(int argv,char* argc[]){pair<int ,int>p1{1,3};cout<<p1.first<<endl;//1cout<<p1.second<<endl;//3
}

1.3、pair交换操作

  • swap(other_pair)
    • 当前pair与另一个pair交换
int main(int argv,char* argc[]){pair<int,int>p1{1,3};pair<int,int> p2=make_pair(2,4);p1.swap(p2);cout<<p1.first<<endl;//2cout<<p1.second<<endl;//4
}

2、初始化map操作

map<KeyType, ValueType> myMap;
键类型 KeyType:必须支持 < 运算符,或传入自定义比较函数。
值类型 ValueType:任意类型(包括自定义类型)。
  • 例子
int main(int argv,char* argc[]){pair<int,int>p1{1,3};pair<int,int>p2{2,4};map<int,int>map1;map<int,int>map2=map1;map<int,int>map3(map2);map<int,int>map4={{1,3},{2,4}};//大括号来初始化map<int,int>map5{{1,3},{2,4}};//大括号来初始化map<int,int>map6={pair<int,int>(3,5)};//使用pairmap<int,int>map7={p1,p2};//使用pair
}
  • 如果我需要不同类型的排序
    • 需要自己重载
map<int, string> m1;                      // 键默认升序
map<int, string, greater<int>> m2;        // 键降序排列// 自定义键类型的比较规则(假设 Key 是自定义类型)
struct Key { int id; string name; };
struct KeyCompare {bool operator()(const Key& a, const Key& b) const {return a.id < b.id || (a.id == b.id && a.name < b.name);}
};
map<Key, string, KeyCompare> customMap;

三、函数使用

1、总结

在这里插入图片描述

2、例子

2.1、插入操作

  • insert( key-value )
    • 直接插入键值
int main(int argv,char* argc[]){map<int,int>map1={pair<int,int>(1,2),pair<int,int>(2,3)};map1.insert(pair<int,int>(3,4));map1.insert({3,4});
}
  • insert({初始化列表})
    • 插入初始化列表
int main(int argv,char* argc[]){map<int,int>map1={pair<int,int>(1,2),pair<int,int>(2,3)};map1.insert({1,3});for(auto i:map1){cout<<i.first<<" "<<i.second<<" ";//1 2 2 3}
}
  • insert(other_first , other_end)
    • 插入另一个map的范围值
int main(int argv,char* argc[]){map<int,int>map1={pair<int,int>(1,2),pair<int,int>(2,3)};map<int,int>map2={pair<int,int>(3,4),pair<int,int>(4,5)};map1.insert(map2.begin(),map2.end());for(auto i:map1){cout<<i.first<<" "<<i.second<<" ";//1 2 2 3 3 4 4 5}
}
  • insert(pos , {key-value})
    • 在pos的位置插入另一个键值,不一定是写成{key-value},也可以写成other_map等等。
int main(int argv,char* argc[]){map<int,int>map1={pair<int,int>(1,2),pair<int,int>(2,3)};map1.insert(map1.begin(),{1,2});for(auto i:map1){cout<<i.first<<" "<<i.second<<" ";//1 2 2 3}
}
  • [ ]运算法
    • 若键存在则修改值,若不存在则创建新元素。
myMap[1] = "one";    // 插入键 1,值为 "one"
myMap[2] = "two";    // 插入键 2,值为 "two"
myMap[1] = "ONE";    // 更新键 1 的值为 "ONE"
  • emplace( )
    • 避免临时对象构造,提高效率。
myMap.emplace(5, "five");  // 直接构造 pair 对象

2.2、删除操作

  • erase(key)
    • 删除键为key的值
int main(int argv,char* argc[]){map<int,int>map1={pair<int,int>(1,2),pair<int,int>(2,3)};map1.erase(1);for(auto i:map1){cout<<i.first<<" "<<i.second<<" ";//2 3}
}
  • erase(fist , end)
    • 删除 在 first 到 end范围内的值
int main(int argv,char* argc[]){map<int,int>map1={pair<int,int>(1,2),pair<int,int>(2,3)};map1.erase(map1.begin(),--map1.end());for(auto i:map1){cout<<i.first<<" "<<i.second<<" ";//2 3}
}

2.3、容量操作

  • empty()
    • 判断是否为空,为空返回 1,否则 0
int main(int argv,char* argc[]){map<int,int>map1={pair<int,int>(1,2),pair<int,int>(2,3)};if(map1.empty()){cout<<"no values"<<endl;}else{cout<<"have values"<<endl;}//have values
}
  • size( )
    • 返回当前值的数量
int main(int argv,char* argc[]){map<int,int>map1={pair<int,int>(1,2),pair<int,int>(2,3)};cout<<map1.size();//2
}

2.4、访问操作

  • [key]运算法
    • 返回key的值
int main(int argv,char* argc[]){map<int,int>map1={pair<int,int>(1,2),pair<int,int>(2,3)};cout<<map1[1];//2
}
  • at(key)
    • 会提醒越界。返回key的值
int main(int argv,char* argc[]){map<int,int>map1={pair<int,int>(1,2),pair<int,int>(2,3)};cout<<map1.at(1);//2
}
  • 迭代器
    • 返回迭代器指针指向的节点
    • 用first和second的获取键和值
    • 节点包括[key和value]
int main(int argv,char* argc[]){map<int,int>map1={pair<int,int>(1,2),pair<int,int>(2,3)};auto i = map1.begin();auto j = --map1.end();cout<<i->second;//2cout<<j->second;//3}

2.5、查找操作

  • find(key)
    • 返回指向键位置的迭代器,未找到返回 end()。
int main(int argv,char* argc[]){map<int,int>map1={pair<int,int>(1,2),pair<int,int>(2,3)};auto i = map1.find(1);cout<<i->second;//2
}
  • count()
    • 返回键出现的次数(0 或 1)。
int main(int argv,char* argc[]){map<int,int>map1={pair<int,int>(1,2),pair<int,int>(2,3)};auto num = map1.count(1);cout<<num;//1
}

2.6、lower_bound和upper_bound

  • lower_bound(key)
    • 首个 >= key的迭代器
int main(int argv,char* argc[]){map<int,int>map1={pair<int,int>(1,2),pair<int,int>(2,3)};auto i = map1.lower_bound(1);cout<<i->first;//1cout<<i->second;//2
}
  • upper_bound(key)
    • 首个 > key的迭代器
int main(int argv,char* argc[]){map<int,int>map1={pair<int,int>(1,2),pair<int,int>(2,3)};auto i = map1.upper_bound(1);cout<<i->first;//2cout<<i->second;//3
}

2.7、交换操作

  • swap(other_map)
    • 交换两个 map
int main(int argv,char* argc[]){map<int,int>map1={pair<int,int>(1,2),pair<int,int>(2,3)};map<int,int>map2={pair<int,int>(3,4)};map1.swap(map2);auto i = map1.begin();cout<<i->first;//3cout<<i->second;//4
}

http://www.ppmy.cn/news/1580726.html

相关文章

SpringBoot 第二课(Ⅰ) 整合springmvc(详解)

目录 一、SpringBoot对静态资源的映射规则 1. WebJars 资源访问 2. 静态资源访问 3. 欢迎页配置 二、SpringBoot整合springmvc 概述 Spring MVC组件的自动配置 中央转发器&#xff08;DispatcherServlet&#xff09; 控制器&#xff08;Controller&#xff09; 视图解…

常用工具: kafka,redis

kafka Apache Kafka 是一个分布式流处理平台&#xff0c;主要用于构建实时数据管道和流应用程序。它具有高吞吐量、低延迟、可扩展性和持久性等特点&#xff0c;广泛应用于日志收集、消息系统、事件溯源、流处理等场景。 以下是 Kafka 的基础知识&#xff1a; 1. Kafka 的核…

深入理解Python闭包与递归:原理、应用与实践

目录 闭包 什么是闭包&#xff1a; 闭包的基本结构&#xff1a; 实现闭包的条件&#xff1a; 1.嵌套函数 2.内函数引用外部函数的变量 3.外部函数返回内部函数 4.外部函数已经执行完毕 递归函数 什么是递归函数&#xff1a; 递归函数条件 1.必须有个明确的结束条…

docker入门篇

使用docker可以很快部署相同的环境,这也是最快的环境构建,接下来就主要对docker中的基础内容进行讲解.Docker 是一个用于开发、交付和运行应用程序的开源平台&#xff0c;它可以让开发者将应用程序及其依赖打包到一个容器中&#xff0c;然后在任何环境中运行这个容器&#xff0…

基于SpringBoot+Vue+uniapp的高校招聘小程序+LW参考示例

系列文章目录 1.基于SSM的洗衣房管理系统原生微信小程序LW参考示例 2.基于SpringBoot的宠物摄影网站管理系统LW参考示例 3.基于SpringBootVue的企业人事管理系统LW参考示例 4.基于SSM的高校实验室管理系统LW参考示例 5.基于SpringBoot的二手数码回收系统原生微信小程序LW参考示…

在react当中利用IntersectionObserve实现下拉加载数据

目录 一、传统的下拉加载方案 二、存在问题 1.性能较差 2.不够精确 三、IntersectionObserve版本下拉加载 1、callback 2、options 四、IntersectionObserver实例 1、Intersection的优势 2、实现思路 3、代码实现 在进行前端开发的过程中&#xff0c;常常会碰到下拉…

31天Python入门——第5天:循环那些事儿

你好&#xff0c;我是安然无虞。 文章目录 1. while循环1.1 while循环的嵌套1.2 补充学习:print函数 2. for循环2.1 range函数2.2 for循环2.3 continue和break以及return2.4 for循环的嵌套 3. 补充学习3.1 enumerate函数3.2 zip函数3.3 不要在遍历列表的过程中删除元素 循环 是…

《数字图像处理》第三章3.3直方图处理学习笔记

请注意:笔记内容片面粗浅&#xff0c;请读者批判着阅读&#xff01; 一、直方图处理的核心理论 1. 直方图均衡化&#xff08;Histogram Equalization&#xff09; 直方图均衡化的目标是将图像的灰度分布调整为近似均匀分布&#xff0c;从而增强对比度。其核心步骤如下&#…