stl map与multimap的使用
map是STL的一个关联容器,它提供一对一(其中第一个可以称为关键字,每个关键字只能在map中出现一次,第二个称为该关键字的值)的数据处理能力,由于这个特性,它完成有可能在我们处理一对一数据的时候,在编程上提供快速通道。这里说下map内部数据的组织,map内部自建一颗红黑树(一 种非严格意义上的平衡二叉树),这颗树具有对数据自动排序的功能,所以在map内部所有的数据都是有序的,后边我们会见识到有序的好处。
multimap:允许关键值重复,重复的关键值可以有不同的val,map不允许关键值重复。
C++ map是一种关联式容器,包含“关键字/值”对
头文件
#include<map>
变量定义
map<int,int> m;
主要函数
begin() 返回指向map头部的迭代器
clear() 删除所有元素
count() 返回指定元素出现的次数
empty() 如果map为空则返回true
end() 返回指向map末尾的迭代器
equal_range() 返回特殊条目的迭代器对
erase() 删除一个元素
find() 查找一个元素
get_allocator() 返回map的配置器
insert() 插入元素
lower_bound() 返回键值>=给定元素的第一个位置
rbegin() 返回一个指向map尾部的逆向迭代器
rend() 返回一个指向map头部的逆向迭代器
size() 返回map中元素的个数
upper_bound() 返回键值>给定元素的第一个位置
实例一
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 | #include<iostream> #include<map> using namespace std; int main() { map< int , string > map1; //定义 map1[13]= "beijing" ; //添加元素key:13,val:beijing map1.insert(map< int , string >::value_type(2, "xian" )); //添加元素key:2,val:xian map1.insert(pair< int , string >(1, "china" )); map1.insert(make_pair< int , string >(4, "V5" )); map< int , string >::iterator it; //map自动按key的值进行排序 for (it=map1.begin();it!=map1.end();it++) { cout<<it->first<< ":" <<it->second<< " " ; } cout<<endl<< "-------" <<endl; map1[13]= "this" ; //修改key为13val为this map1.insert(pair< int , string >(1, "China" )); //不会修改key为1的val map1.insert(make_pair< int , string >(4, "V6" )); //不会修改 map1.insert(map< int , string >::value_type(2, "Xian" )); //不会修改 for (it=map1.begin();it!=map1.end();it++) { cout<<it->first<< ":" <<it->second<< " " ; //it->first获取key的值,it->second获取val的值 } cout<<endl<< "-------" <<endl; cout<<map1.find(1)->second<<endl; //cout<<map1.find(19)->second<<endl; 注意这里没有key为19的值,故运行时会出错 //因此查找key的val值正确的做法应为 it=map1.find(19); if (it==map1.end()) { cout<< "No found" <<endl; //没有查找成功时 } else { cout<<it->second<<endl; } it=map1.find(1); if (it==map1.end()) { cout<< "No found" <<endl; //没有查找成功时 } else { cout<<it->second<<endl; } it=map1.lower_bound(2); if (it!=map1.end()) { cout<<it->first<< ":" <<it->second<<endl; } it=map1.upper_bound(2); if (it!=map1.end()) { cout<<it->first<< ":" <<it->second<<endl; } map1.erase(2); for (it=map1.begin();it!=map1.end();it++) { cout<<it->first<< ":" <<it->second<< " " ; //it->first获取key的值,it->second获取val的值 } cout<<endl<< "-------" <<endl; map1.erase(8); for (it=map1.begin();it!=map1.end();it++) { cout<<it->first<< ":" <<it->second<< " " ; //it->first获取key的值,it->second获取val的值 } cout<<endl<< "-------" <<endl; return 0; } |
实例二
1)根据要删除的键值对位于容器中的位置,实现删除该键值对。
//删除map容器种指定位置的键值对
iterator erase(const_iterator position);
其中,position为迭代器,指向要删除的键值对。
该方法会返回一个iterator迭代器,其指向的是删除键值对之后的那个键值对(如果是删除最后一个键值对,那么该方法也会返回迭代器指向的最后一个键值对之后的位置)。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | #include<iostream> #include<map> #include<string> using namespace std; int main() { //创建并初始化map容器 map< string , int > myMap{{ "penny" ,1},{ "leonard" ,2},{ "sheldon" ,3},{ "howard" ,4}}; cout<<myMap.size()<<endl; //输出键值对个数 //遍历map容器 for (auto iter = myMap.begin(); iter != myMap.end(); iter++){ cout<<iter->first<< "," <<iter->second<< " " ; } cout<<endl; //创建一个指向要删除键值对的迭代器 map< string , int >::iterator iter = ++myMap.begin(); //指向第二个键值对 //执行删除操作 map< string , int >::iterator ret = myMap.erase(iter); cout<<myMap.size()<<endl; //输出键值对个数 //输出erase()方法返回的迭代器指向的键值对 cout<<ret->first<< " " <<ret->second<<endl; return 0; } |
实例三
2)传入要删除目标键值对的键的值,该方法会自行根据指定的键找到目标键值对,并将其删除。
//删除map容器种键为k的键值对
size_type erase(const key_type& k);
其中,参数k为要删除的键值对的键的值。
该方法的返回值为成功删除的键值对的个数。由于map容器种每个键值对的键都是独一无二的,故其返回值最大为1.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | #include<iostream> #include<map> #include<string> using namespace std; int main() { //创建并初始化map容器 map< string , int > myMap{{ "penny" ,1},{ "leonard" ,2},{ "sheldon" ,3},{ "howard" ,4}}; cout<<myMap.size()<<endl; //输出键值对个数 //执行删除操作,删除myMap容器种键为"penny"的键值对 int num = myMap.erase( "penny" ); cout<<myMap.size()<<endl; //输出键值对个数 //输出erase()方法的返回值 cout<< "num= " <<num<<endl; return 0; } |
实例四
3)在某些情况下,可能需要删除某个指定区域内的所有键值对,也可以通过erase()方法实现。
//删除 map 容器中位于 [first,last) 区域内的所有键值对
iterator erase (const_iterator first, const_iterator last);
其中参数first和last都是迭代器,[first, last)就表示map容器种的某个范围,该方法会删除此范围内的所有键值对。
返回值为一个迭代器,其指向删除范围之后的第一个键值对。如果该范围之后,不再有任何键值对,则返回的迭代器指向map容器最后一个键值对之后的位置。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | #include<iostream> #include<map> #include<string> using namespace std; int main(){ //创建并初始化map容器 map< string , int > myMap{{ "penny" ,1},{ "leonard" ,2},{ "sheldon" ,3},{ "howard" ,4}}; cout<<myMap.size()<<endl; //输出键值对个数 //指定范围 map< string , int >::iterator first = myMap.begin(); map< string , int >::iterator last = --myMap.end(); //删除指定范围内的容器 map< string , int >::iterator ret = myMap.erase(first,last); cout<<myMap.size()<<endl; cout<<ret->first<< " " <<ret->second<<endl; return 0; } |
实例五:
insert插入相同键值时不会改变原有的值
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 | #include<bits/stdc++.h> using namespace std; map< int , int > ma; int main() { int n; cin>>n; for ( int i=1;i<=n;i++) { int x,y; cin>>x>>y; ma.insert(pair< int , int > (x,y)); //插入相同键值的时候不会改变 map< int , int >::iterator it; for (it=ma.begin();it!=ma.end();it++) { cout<<(it->first)<< " " <<(it->second)<<endl; } cout<< "----" <<endl; } } /* in 8 4 5 4 3 1 2 3 7 3 8 8 9 4 0 5 6 out 8 4 5 ---- 4 5 ---- 1 2 4 5 ---- 1 2 3 7 4 5 ---- 1 2 3 7 4 5 ---- 1 2 3 7 4 5 8 9 ---- 1 2 3 7 4 5 8 9 ---- 1 2 3 7 4 5 5 6 8 9 ---- */ |
使用数组形式可以改变原有的值
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 | #include<bits/stdc++.h> using namespace std; map< int , int > ma; int main() { int n; cin>>n; for ( int i=1;i<=n;i++) { int x,y; cin>>x>>y; ma[x]=y; //数组方式可以修改原有的值 map< int , int >::iterator it; for (it=ma.begin();it!=ma.end();it++) { cout<<(it->first)<< " " <<(it->second)<<endl; } cout<< "----" <<endl; } } /* in 8 4 5 4 3 1 2 3 7 3 8 8 9 4 0 5 6 out 4 5 ---- 4 3 ---- 1 2 4 3 ---- 1 2 3 7 4 3 ---- 1 2 3 8 4 3 ---- 1 2 3 8 4 3 8 9 ---- 1 2 3 8 4 0 8 9 ---- 1 2 3 8 4 0 5 6 8 9 ---- */ |
multimap不支特数组的插入形式
map使用结构体的实例
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 | //当元素为结构体时自定义排序 #include <iostream> #include <map> #include <utility> using namespace std; struct Info { string name; float score; //重载"<"操作符,自定义排序规则 bool operator < ( const Info &a) const { if (score==a.score) return name>a.name; return score>a.score; } }; int main() { map<Info, int > m; Info info; info.name= "Jack" ; info.score=60; m[info]=25; info.name= "Tom" ; info.score=60; m[info]=30; info.name= "Bomi" ; info.score=80; m[info]=10; info.name= "Peti" ; info.score=66.5; m[info]=30; map<Info, int >::iterator it; for (it=m.begin();it!=m.end();it++) { cout<<(*it).second<< " : " ; cout<<((*it).first).name<< " " <<((*it).first).score<<endl; } return 0; } |
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· C#/.NET/.NET Core优秀项目和框架2025年2月简报
· Manus爆火,是硬核还是营销?
· 一文读懂知识蒸馏
· 终于写完轮子一部分:tcp代理 了,记录一下