STL容器中的map容器 map的基本概念 map的特点 map的构造 map的赋值 map的插入 map的删除 map的大小 map的交换查找,统计 map的排序
无题二首·其一 李商隐 昨夜星辰昨夜风,画楼西畔桂堂东。 身无彩凤双飞翼,心有灵犀一点通。 隔座送钩春酒暖,分曹射覆蜡灯红。 嗟余听鼓应官去,走马兰台类转蓬。
map的基本概念
map是一种关联容器,也被称为字典,底层结构是二叉树。 它以键值对key,value的形式存储元素。其中key是唯一的,用于快速查找对应的value。 如果尝试插入具有相同key的元素,旧的值将被新的覆盖。 map提供双向迭代器,可以遍历容器中的所有键值对。 迭代器指向的是pair类型的对象,first成员属性是key,second成员属性是value multimap的key值是可以重复的,其它的与map类似。
map的特点
有序性,map中的元素是按照key的特定顺序存储的,默认情况下是key的升序排列,可以按照顺序遍历map中的元素,并可以进行范围查询等操作。 map中的key有唯一性,multimap则无。 高效的查找和插入。 map以键值对的方式存储元素,方便将相关的数据关联在一起。 可以通过自定义的比较函数来改变key的排序规则。
map的构造
构造函数 描述 map<type1, type2> mp1 默认构造函数 map<type1, type2> mp2(mp1) 拷贝构造 map<type1, type2> mp2{{},{}…} 初始化列表构造 map<type1, type2> mp4(迭代器1, 迭代器2 范围构造 map<type1, type2> mp5(move(mp1) 直接移动,并不拷贝
code:
# include <iostream>
# include <map>
# include <vector>
# include <algorithm>
using namespace std; template < typename T1 , typename T2 >
void print_map ( const map< T1, T2> & mp)
{ for ( auto i_mp: mp) { cout << "first: " << i_mp. first << ", second: " << i_mp. second << endl; }
}
void test01 ( )
{ map< string, int > mp1; pair< string, int > pr1 ( "Lily" , 9 ) ; pair< string, int > pr2 ( "Lucy" , 10 ) ; mp1. insert ( pr1) ; mp1. insert ( pr2) ; cout << "---------- mp1, mp1.size() ---------- " << mp1. size ( ) << endl; print_map ( mp1) ; cout << "value of key Lily: " << mp1[ "Lily" ] << endl; map< string, int > mp2 ( mp1) ; cout << "---------- map<string, int> mp2(mp1), mp2 ---------- " << mp2. size ( ) << endl; print_map ( mp2) ; map< string, int > mp3{ { "Hanmeimei" , 9 } , { "Poly" , 2 } } ) cout << "---------- map<string, int> mp3({{},{},...}), mp3 ---------- " << mp3. size ( ) << endl; print_map ( mp3) ; vector< pair< string, int >> vec1 = { { "张三" , 5 } , { "李四" , 6 } , { "王五" , 7 } } ; map< string, int > mp4 ( vec1. begin ( ) , vec1. begin ( ) + 2 ) ; cout << "---------- map<string, int> mp4(vec1.begin(), vec1.begin() + 2), mp4 ---------- " << mp4. size ( ) << endl; print_map ( mp4) ; cout << "---------- 移动构造前 ----------" << endl; cout << "mp3.size(): " << mp3. size ( ) << endl; map< string, int > mp5 ( move ( mp3) ) ; cout << "---------- 移动构造后 ----------" << endl; cout << "---------- map<string, int> mp5(move(mp3)) ---------- " << mp5. size ( ) << endl; print_map ( mp5) ; cout << "mp3.size(): " << mp3. size ( ) << endl; print_map ( mp3) ;
}
int main ( )
{ test01 ( ) ; system ( "pause" ) ; return 0 ;
} result:
-- -- -- -- -- mp1, mp1. size ( ) -- -- -- -- -- 2
first: Lily, second: 9
first: Lucy, second: 10
value of key Lily: 9
-- -- -- -- -- map< string, int > mp2 ( mp1) , mp2 -- -- -- -- -- 2
first: Lily, second: 9
first: Lucy, second: 10
-- -- -- -- -- map< string, int > mp3 ( { { } , { } , . . . } ) , mp3 -- -- -- -- -- 2
first: Hanmeimei, second: 9
first: Poly, second: 2
-- -- -- -- -- map< string, int > mp4 ( vec1. begin ( ) , vec1. begin ( ) + 2 ) , mp4 -- -- -- -- -- 2
first: 李四, second: 6
first: 张三, second: 5
-- -- -- -- -- 移动构造前 -- -- -- -- --
mp3. size ( ) : 2
-- -- -- -- -- 移动构造后 -- -- -- -- --
-- -- -- -- -- map< string, int > mp5 ( move ( mp3) ) -- -- -- -- -- 2
first: Hanmeimei, second: 9
first: Poly, second: 2
mp3. size ( ) : 0
map的赋值
code:
# include <iostream>
# include <map>
# include <vector>
# include <algorithm>
using namespace std; template < typename T1 , typename T2 >
void print_map ( const map< T1, T2> & mp)
{ for ( auto i_mp : mp) { cout << "first: " << i_mp. first << ", second: " << i_mp. second << endl; }
}
void test01 ( )
{ map< string, int > mp1{ { "Lily" , 9 } , { "Lucy" , 10 } } ; cout << "---------- mp1, mp1.size() ---------- " << mp1. size ( ) << endl; print_map ( mp1) ; map< string, int > mp2 = mp1; cout << "---------- map<string, int> mp2 = mp1, mp2 ---------- " << mp2. size ( ) << endl; print_map ( mp2) ;
}
int main ( )
{ test01 ( ) ; system ( "pause" ) ; return 0 ;
} result:
-- -- -- -- -- mp1, mp1. size ( ) -- -- -- -- -- 2
first: Lily, second: 9
first: Lucy, second: 10
-- -- -- -- -- map< string, int > mp2 = mp1, mp2 -- -- -- -- -- 2
first: Lily, second: 9
first: Lucy, second: 10
map的插入
构造函数 描述 pair<iterator, bool> insert(pair<type ,type2>(key, value)) insert插入pair,返回值是pair,第一个元素时迭代器,迭代器所指值的第一个元素是key,第二个是value,pair中的second元素bool类型表示是否插入成功 pair<iterator, bool> insert(make_pair(key, value)) insert插入pair,pair由make_pair产生,返回值同上 pair<iterator, bool> insert(map<type1, type2>::value_type(key, value)) 使用type_value函数产生pair对象,返回值同上 mapped_type& mp1[value]=value []插入法, 如果插错了,比如key写错了,会自动创建一个对应这个key的元素,value设置为0,建议少用,但[]通过key访问value很方便 void insert({ val1, val2, … }) 一次向 map 容器中插入多个键值对 void insert (InputIterator first, InputIterator last) 插入某map容器中的指定区域 iterator insert (const_iterator position, const value_type& val) 会按照key自动排序,不按照position的指示
code:
# include <iostream>
# include <map>
using namespace std; template < typename T1 , typename T2 >
void print_map ( const map< T1, T2> & mp)
{ for ( auto i_mp : mp) { cout << "first: " << i_mp. first << ", second: " << i_mp. second << endl; }
}
void test01 ( )
{ map< string, int > mp1{ { "Lily" , 9 } , { "Lucy" , 10 } } ; auto pr1 = mp1. insert ( pair < string, int > ( "Jim" , 10 ) ) ; cout << "----- pr1.first->first: " << pr1. first-> first << ", pr1.first->second: " << pr1. first-> second << ", pr1.second: " << pr1. second << endl; auto pr2 = mp1. insert ( make_pair ( "Poly" , 2 ) ) ; cout << "----- pr2.first->first: " << pr2. first-> first << ", pr2.first->second: " << pr2. first-> second << ", pr2.second: " << pr2. second << endl; auto pr3 = mp1. insert ( map < string, int > :: value_type ( "Hanmeimei" , 11 ) ) ; cout << "----- pr3.first->first: " << pr3. first-> first << ", pr3.first->second: " << pr3. first-> second << ", pr3.second: " << pr3. second << endl; mp1[ "MissGao" ] = 33 ; mp1. insert ( { { "张三" , 12 } , { "李四" , 11 } , { "王五" , 11 } } ) ; print_map ( mp1) ;
}
int main ( )
{ test01 ( ) ; system ( "pause" ) ; return 0 ;
} result:
-- -- - pr1. first-> first: Jim, pr1. first-> second: 10 , pr1. second: 1
-- -- - pr2. first-> first: Poly, pr2. first-> second: 2 , pr2. second: 1
-- -- - pr3. first-> first: Hanmeimei, pr3. first-> second: 11 , pr3. second: 1
first: Hanmeimei, second: 11
first: Jim, second: 10
first: Lily, second: 9
first: Lucy, second: 10
first: MissGao, second: 33
first: Poly, second: 2
first: 李四, second: 11
first: 王五, second: 11
first: 张三, second: 12
code:
# include <iostream>
# include <map>
using namespace std; template < typename T1 , typename T2 >
void print_map ( const map< T1, T2> & mp)
{ for ( auto i_mp : mp) { cout << "first: " << i_mp. first << ", second: " << i_mp. second << endl; }
}
void test01 ( )
{ cout << "---------- mp1 ----------" << endl; map< string, int > mp1{ { "Lily" , 9 } , { "Lucy" , 10 } } ; mp1. insert ( { { "张三" , 12 } , { "李四" , 11 } , { "王五" , 11 } } ) ; print_map ( mp1) ; cout << "---------- mp2 ----------" << endl; map< string, int > mp2; auto it = mp1. find ( "王五" ) ; mp2. insert ( mp1. begin ( ) , it) ; print_map ( mp2) ; cout << "---------- mp3 ----------" << endl; map< string, int > mp3{ { "吴彦祖" , 48 } , { "金城武" , 46 } } ; map< string, int > :: iterator iter1 = mp3. insert ( mp3. find ( "吴彦祖" ) , { "古天乐" , 18 } ) ; print_map ( mp3) ; cout << "\nreturn value check" << endl; cout << "first: " << iter1-> first << ", second: " << iter1-> second << endl;
}
int main ( )
{ test01 ( ) ; system ( "pause" ) ; return 0 ;
} result:
-- -- -- -- -- mp1 -- -- -- -- --
first: Lily, second: 9
first: Lucy, second: 10
first: 李四, second: 11
first: 王五, second: 11
first: 张三, second: 12
-- -- -- -- -- mp2 -- -- -- -- --
first: Lily, second: 9
first: Lucy, second: 10
first: 李四, second: 11
-- -- -- -- -- mp3 -- -- -- -- --
first: 古天乐, second: 18
first: 金城武, second: 46
first: 吴彦祖, second: 48 return value check
first: 古天乐, second: 18
map的删除
构造函数 描述 iterator erase(const_iterator position) 有的版本是返回删除的元素的迭代器,有的是返回其下一个 size_type erase (const key_type& k) 返回删除了几个元素,map只能为0和1,multimap可以有多个 iterator erase(const_iterator first, const_iterator last) 有的版本是返回删除的元素的迭代器,有的是返回其下一个
code:
# include <iostream>
# include <map>
using namespace std; template < typename T1 , typename T2 >
void print_map ( const map< T1, T2> & mp)
{ for ( auto i_mp : mp) { cout << "first: " << i_mp. first << ", second: " << i_mp. second << endl; }
}
void test01 ( )
{ cout << "---------- mp1 ----------" << endl; map< string, int > mp1{ { "Lily" , 9 } , { "Lucy" , 10 } } ; mp1. insert ( { { "张三" , 12 } , { "李四" , 11 } , { "王五" , 11 } } ) ; print_map ( mp1) ; map< string, int > :: iterator it = mp1. erase ( mp1. find ( "张三" ) ) ; cout << "it->first: " << ( -- it) -> first << endl; int st1 = mp1. erase ( "李四" ) ; cout << "int st1 = mp1.erase(key)" << endl; cout << "---------- mp1 ----------" << endl; print_map ( mp1) ; it = mp1. erase ( mp1. begin ( ) , -- mp1. end ( ) ) ; cout << endl; cout << "mp1.erase(mp1.begin(), --mp1.end())" << endl; print_map ( mp1) ; cout << "it->first: " << it-> first << endl; mp1. clear ( ) ; cout << "mp1.clear(), mp1.size(): " << mp1. size ( ) << endl; print_map ( mp1) ;
}
int main ( )
{ test01 ( ) ; system ( "pause" ) ; return 0 ;
} result:
-- -- -- -- -- mp1 -- -- -- -- --
first: Lily, second: 9
first: Lucy, second: 10
first: 李四, second: 11
first: 王五, second: 11
first: 张三, second: 12
it-> first: 王五
int st1 = mp1. erase ( key)
-- -- -- -- -- mp1 -- -- -- -- --
first: Lily, second: 9
first: Lucy, second: 10
first: 王五, second: 11 mp1. erase ( mp1. begin ( ) , -- mp1. end ( ) )
first: 王五, second: 11
it-> first: 王五
mp1. clear ( ) , mp1. size ( ) : 0
map的大小
构造函数 描述 size() 返回map容器的大小 empty() 返回map容器是否为空
map的交换查找,统计
|:--------😐:-------------| |find() |如果查找到,返回查找到的迭代器,否则返回end() | |count()|map的统计count(),map返回0或者1 | |sort()|map的排序 |
code:
# include <iostream>
# include <map>
using namespace std; template < typename T1 , typename T2 >
void print_map ( const map< T1, T2> & mp)
{ for ( auto i_mp : mp) { cout << "first: " << i_mp. first << ", second: " << i_mp. second << endl; }
}
void test01 ( )
{ map< string, int > mp1{ { "Lily" , 9 } , { "Lucy" , 10 } } ; mp1. insert ( { { "张三" , 12 } , { "李四" , 11 } , { "王五" , 11 } } ) ; cout << "---------- mp1.size() ----------, " << mp1. size ( ) << endl; print_map ( mp1) ; map< string, int > mp2; mp2[ "1" ] = 111 ; mp2[ "2" ] = 222 ; mp2[ "3" ] = 333 ; cout << "---------- swap前----------, " << endl; print_map ( mp1) ; print_map ( mp2) ; cout << "---------- swap后----------, " << endl; mp1. swap ( mp2) ; print_map ( mp1) ; print_map ( mp2) ; map< string, int > :: iterator it = mp2. find ( "2" ) ; cout << "---------- mp2.find(\"2\")----------, " << endl; cout << "it->first: " << ( -- it) -> first << endl; int mp_count = mp1. count ( "3" ) ; cout << "---------- mp1.count(\"1\")----------, " << endl; cout << "mp_count: " << mp_count << endl;
}
int main ( )
{ test01 ( ) ; system ( "pause" ) ; return 0 ;
} result:
-- -- -- -- -- mp1. size ( ) -- -- -- -- -- , 5
first: Lily, second: 9
first: Lucy, second: 10
first: 李四, second: 11
first: 王五, second: 11
first: 张三, second: 12
-- -- -- -- -- swap前-- -- -- -- -- ,
first: Lily, second: 9
first: Lucy, second: 10
first: 李四, second: 11
first: 王五, second: 11
first: 张三, second: 12
first: 1 , second: 111
first: 2 , second: 222
first: 3 , second: 333
-- -- -- -- -- swap后-- -- -- -- -- ,
first: 1 , second: 111
first: 2 , second: 222
first: 3 , second: 333
first: Lily, second: 9
first: Lucy, second: 10
first: 李四, second: 11
first: 王五, second: 11
first: 张三, second: 12
-- -- -- -- -- mp2. find ( "2" ) -- -- -- -- -- ,
it-> first: 张三
-- -- -- -- -- mp1. count ( "1" ) -- -- -- -- -- ,
mp_count: 1
map的排序
map的排序都是按照key来排序的,在创建map容器时就要指定好排序方式。 对于普通数据类型会自动按照升序,如果要改变,可以自己写排序方式。 自定义类型在创建时需要指定好排序规则,不然系统不知道怎么给排序,无法创建
code:
# include <iostream>
# include <map>
using namespace std; class Person
{ friend class MyComparePerson ; template < typename T1 , typename T2 , typename T3 > friend void print_map ( const map< T1, T2, T3> & mp) ; template < typename Person , typename T2 > friend void print_map ( const map< Person, T2, MyComparePerson> & mp) ; public : Person ( string name, int age) { m_name = name; m_age = age; }
private : string m_name; int m_age;
} ;
template < class T >
class MyCompare
{
public : bool operator ( ) ( const T & v1, const T & v2) const { return v1 > v2; }
} ; class MyComparePerson
{
public : bool operator ( ) ( const Person & p1, const Person & p2) const { return p1. m_age > p2. m_age; }
} ; template < typename T1 , typename T2 >
void print_map ( const map< T1, T2, MyCompare< string>> & mp)
{ for ( auto i_mp : mp) { cout << "first: " << i_mp. first << ", second: " << i_mp. second << endl; }
} template < typename Person , typename T2 >
void print_map ( const map< Person, T2, MyComparePerson> & mp)
{ for ( auto i_mp : mp) { cout << "key.m_name: " << i_mp. first. m_name << ", key.m_age: " << i_mp. first. m_age << ", value: " << i_mp. second << endl; }
} void test01 ( )
{ map< string, int , MyCompare< string>> mp2{ { "1" , 20 } , { "2" , 30 } , { "3" , 60 } } ; print_map ( mp2) ;
} void test02 ( )
{ map< Person, int , MyComparePerson> mp1; Person p1 ( "lily" , 12 ) ; Person p2 ( "Lucy" , 15 ) ; Person p3 ( "Jim" , 17 ) ; mp1. insert ( { { p1, 33 } , { p2, 22 } , { p3, 77 } } ) ; print_map ( mp1) ;
} int main ( )
{ test01 ( ) ; test02 ( ) ; system ( "pause" ) ; return 0 ;
} result:
first: 3 , second: 60
first: 2 , second: 30
first: 1 , second: 20
key. m_name: Jim, key. m_age: 17 , value: 77
key. m_name: Lucy, key. m_age: 15 , value: 22
key. m_name: lily, key. m_age: 12 , value: 33