std::map 简介及其使用
注:std::map C++11标准
map概述
template < class Key, // map::key_type class T, // map::mapped_type class Compare = less<Key>, // map::key_compare class Alloc = allocator<pair<const Key,T> > // map::allocator_type > class map;
Map是一种关联容器,它按照特定顺序存储由键值Key和映射值Value组合而成的元素。
在map中,键值Key通常用于排序和唯一标识元素,而映射值Value存储与此键值Key相关联的内容。键Key和映射值Value的类型可能不同,并在成员类型value_type中组合在一起,value_type是一个组合了这两种类型的pair类型:typedef pair<const Key, T> value_type。
在map内部,元素总是按照其键Key进行排序的,排序时使用其内部比较对象(Compare)并遵循指定的严格弱序准则。
Map容器通常比unordered_map容器在按键Key访问元素的速度上要慢,但它们允许根据子集的顺序直接迭代子集。
Map中的映射值可以通过对应的键Key使用括号操作符(operator[])直接访问。
Map通常是基于二叉搜索树实现的。
容器属性
- 关联
关联容器中的元素由其键引用,而不是由它们在容器中的绝对位置引用。
- 有序
容器中的元素始终遵循严格的顺序。所有插入的元素都按这个顺序给定一个位置。
- 映射
每个元素都将一个键关联到一个映射值:键用于标识其内容为映射值的元素。
- 键值唯一
容器中没有两个元素可以具有等效键。
- 分配器
容器使用allocator对象来动态处理其存储需求。
模板参数
- Key
键的类型。Map中的每个元素都由其键值唯一标识。别名为成员类型map::key_type。
- T
映射值的类型。Map中的每个元素都将一些数据存储为其映射值。别名为成员类型map::mapped_type
- Compare
一个二进制谓词,它接受两个键值作为参数并返回一个bool值。表达式 comp(a, b) 中,comp是Compare类型的对象,a和b是键值,如果在函数定义的严格弱序中,a被认为在b之前,则表达式comp(a, b)应该返回true。Map对象使用这个表达式来确定容器中元素的顺序以及两个元素的键是否相等。Map容器中的任何两个元素都不能具有相同的键。Compare可以是函数指针或函数对象,默认为 less<T>,其返回与使用小于操作符(a<b)相同的结果。别名为成员类型map::key_compare。
- Alloc
分配器对象的类型,用于定义存储分配模型。默认情况下,使用allocator类模板,该模板定义最简单的内存分配模型,并且与值无关。别名为成员类型map::allocator_type。
成员类型
member type | definition | notes |
---|---|---|
key_type | The first template parameter (Key) | |
mapped_type | The second template parameter (T) | |
value_type | pair<const key_type,mapped_type> | |
key_compare | The third template parameter (Compare) | defaults to: less<key_type> |
value_compare | Nested function class to compare elements | see value_comp |
allocator_type | The fourth template parameter (Alloc) | defaults to: allocator<value_type> |
reference | value_type& | |
const_reference | const value_type& | |
pointer | allocator_traits<allocator_type>::pointer | for the default allocator: value_type* |
const_pointer | allocator_traits<allocator_type>::const_pointer | for the default allocator: const value_type* |
iterator | a bidirectional iterator to value_type | convertible to const_iterator |
const_iterator | a bidirectional iterator to const value_type | |
reverse_iterator | reverse_iterator<iterator> | |
const_reverse_iterator | reverse_iterator<const_iterator> | |
difference_type | a signed integral type, identical to: iterator_traits<iterator>::difference_type |
usually the same as ptrdiff_t |
size_type | an unsigned integral type that can represent any non-negative value of difference_type | usually the same as size_t |
成员函数
- 构造函数(constructor)
empty (1) |
explicit map (const key_compare& comp = key_compare(), const allocator_type& alloc = allocator_type()); explicit map (const allocator_type& alloc); |
---|---|
range (2) |
template <class InputIterator> map (InputIterator first, InputIterator last, const key_compare& comp = key_compare(), const allocator_type& = allocator_type()); |
copy (3) |
map (const map& x); map (const map& x, const allocator_type& alloc); |
move (4) |
map (map&& x); map (map&& x, const allocator_type& alloc); |
initializer list (5) |
map (initializer_list<value_type> il, const key_compare& comp = key_compare(), const allocator_type& alloc = allocator_type()); |
构造函数示例:
// constructing maps #include <iostream> #include <map> bool fncomp (char lhs, char rhs) {return lhs<rhs;} struct classcomp { bool operator() (const char& lhs, const char& rhs) const {return lhs<rhs;} }; int main () { std::map<char,int> first; first['a']=10; first['b']=30; first['c']=50; first['d']=70; std::map<char,int> second (first.begin(),first.end()); std::map<char,int> third (second); std::map<char,int,classcomp> fourth; // class as Compare bool(*fn_pt)(char,char) = fncomp; std::map<char,int,bool(*)(char,char)> fifth (fn_pt); // function pointer as Compare return 0; }
- 析构函数(destructor)
~map();
- 赋值(operator=)
copy (1) |
map& operator= (const map& x); |
---|---|
move (2) |
map& operator= (map&& x); |
initializer list (3) |
map& operator= (initializer_list<value_type> il); |
赋值示例:
// assignment operator with maps #include <iostream> #include <map> int main () { std::map<char,int> first; std::map<char,int> second; first['x']=8; first['y']=16; first['z']=32; second=first; // second now contains 3 ints first=std::map<char,int>(); // and first is now empty std::cout << "Size of first: " << first.size() << '\n'; std::cout << "Size of second: " << second.size() << '\n'; return 0; } Output: Size of first: 0 Size of second: 3
- 迭代器(Iterators)
迭代器示例:
// map::begin/end #include <iostream> #include <map> int main () { std::map<char,int> mymap; mymap['b'] = 100; mymap['a'] = 200; mymap['c'] = 300; // show content: for (std::map<char,int>::iterator it=mymap.begin(); it!=mymap.end(); ++it) std::cout << it->first << " => " << it->second << '\n'; return 0; } Output: a => 200 b => 100 c => 300
- 容器大小或容量相关(Capacity)
函数 | 函数原型 | 功能描述 |
empty | bool empty() const noexcept; | Test whether container is empty |
size | size_type size() const noexcept; | Return container size |
max_size | size_type max_size() const noexcept; | Return maximum size |
- 成员访问(Element access)
函数 | 函数原型 | 功能描述 |
operator[] | mapped_type& operator[] (const key_type& k); | Access element |
mapped_type& operator[] (key_type&& k); | ||
at | mapped_type& at (const key_type& k); | Access element |
const mapped_type& at (const key_type& k) const; |
成员访问示例:
// accessing mapped values #include <iostream> #include <map> #include <string> int main () { std::map<char,std::string> mymap; mymap['a']="an element"; mymap['b']="another element"; mymap['c']=mymap['b']; std::cout << "mymap['a'] is " << mymap['a'] << '\n'; std::cout << "mymap['b'] is " << mymap['b'] << '\n'; std::cout << "mymap['c'] is " << mymap['c'] << '\n'; std::cout << "mymap['d'] is " << mymap['d'] << '\n'; std::cout << "mymap now contains " << mymap.size() << " elements.\n"; return 0; } Notice how the last access (to element 'd') inserts a new element in the map with that key and initialized to its default value (an empty string) even though it is accessed only to retrieve its value. Member function map::find does not produce this effect. Output: mymap['a'] is an element mymap['b'] is another element mymap['c'] is another element mymap['d'] is mymap now contains 4 elements. ---------------------------------------------------------------------------------------- // map::at #include <iostream> #include <string> #include <map> int main () { std::map<std::string,int> mymap = { { "alpha", 0 }, { "beta", 0 }, { "gamma", 0 } }; mymap.at("alpha") = 10; mymap.at("beta") = 20; mymap.at("gamma") = 30; for (auto& x: mymap) { std::cout << x.first << ": " << x.second << '\n'; } return 0; } Possible output: alpha: 10 beta: 20 gamma: 30 成员访问示例
- 添加、删除等修改相关操作(Modifiers)
函数 | 函数原型 | 功能描述 |
insert | pair<iterator,bool> insert (const value_type& val); template <class P> pair<iterator,bool> insert (P&& val); |
Insert elements |
iterator insert (const_iterator position, const value_type& val); template <class P> iterator insert (const_iterator position, P&& val); |
||
template <class InputIterator> void insert (InputIterator first, InputIterator last); |
||
void insert (initializer_list<value_type> il); | ||
erase | iterator erase (const_iterator position); | Erase elements |
size_type erase (const key_type& k); | ||
iterator erase (const_iterator first, const_iterator last); | ||
swap | void swap (map& x); | Swap content |
clear | void clear() noexcept; | Clear content |
emplace | template <class... Args> pair<iterator,bool> emplace (Args&&... args); |
Construct and insert element |
emplace_hint | template <class... Args> iterator emplace_hint (const_iterator position, Args&&... args); |
Construct and insert element with hint |
示例代码:
// map::insert #include <iostream> #include <map> int main () { std::map<char,int> mymap; mymap.insert ( std::pair<char,int>('a',100) ); mymap.insert ( std::pair<char,int>('z',200) ); std::pair<std::map<char,int>::iterator,bool> ret; ret = mymap.insert ( std::pair<char,int>('z',500) ); if (ret.second==false) { std::cout << "element 'z' already existed"; std::cout << " with a value of " << ret.first->second << '\n'; } std::map<char,int>::iterator it = mymap.begin(); mymap.insert (it, std::pair<char,int>('b',300)); // max efficiency inserting mymap.insert (it, std::pair<char,int>('c',400)); // no max efficiency inserting std::map<char,int> anothermap; anothermap.insert(mymap.begin(),mymap.find('c')); // showing contents: std::cout << "mymap contains:\n"; for (it=mymap.begin(); it!=mymap.end(); ++it) std::cout << it->first << " => " << it->second << '\n'; std::cout << "anothermap contains:\n"; for (it=anothermap.begin(); it!=anothermap.end(); ++it) std::cout << it->first << " => " << it->second << '\n'; return 0; } Output: element 'z' already existed with a value of 200 mymap contains: a => 100 b => 300 c => 400 z => 200 anothermap contains: a => 100 b => 300 ----------------------------------------------------------------------------------------- // erasing from map #include <iostream> #include <map> int main () { std::map<char,int> mymap; std::map<char,int>::iterator it; // insert some values: mymap['a']=10; mymap['b']=20; mymap['c']=30; mymap['d']=40; mymap['e']=50; mymap['f']=60; it=mymap.find('b'); mymap.erase (it); // erasing by iterator mymap.erase ('c'); // erasing by key it=mymap.find ('e'); mymap.erase ( it, mymap.end() ); // erasing by range // show content: for (it=mymap.begin(); it!=mymap.end(); ++it) std::cout << it->first << " => " << it->second << '\n'; return 0; } Output: a => 10 d => 40 ----------------------------------------------------------------------------------------- // swap maps #include <iostream> #include <map> int main () { std::map<char,int> foo,bar; foo['x']=100; foo['y']=200; bar['a']=11; bar['b']=22; bar['c']=33; foo.swap(bar); std::cout << "foo contains:\n"; for (std::map<char,int>::iterator it=foo.begin(); it!=foo.end(); ++it) std::cout << it->first << " => " << it->second << '\n'; std::cout << "bar contains:\n"; for (std::map<char,int>::iterator it=bar.begin(); it!=bar.end(); ++it) std::cout << it->first << " => " << it->second << '\n'; return 0; } Output: foo contains: a => 11 b => 22 c => 33 bar contains: x => 100 y => 200 ----------------------------------------------------------------------------------------- // map::clear #include <iostream> #include <map> int main () { std::map<char,int> mymap; mymap['x']=100; mymap['y']=200; mymap['z']=300; std::cout << "mymap contains:\n"; for (std::map<char,int>::iterator it=mymap.begin(); it!=mymap.end(); ++it) std::cout << it->first << " => " << it->second << '\n'; mymap.clear(); mymap['a']=1101; mymap['b']=2202; std::cout << "mymap contains:\n"; for (std::map<char,int>::iterator it=mymap.begin(); it!=mymap.end(); ++it) std::cout << it->first << " => " << it->second << '\n'; return 0; } Output: mymap contains: x => 100 y => 200 z => 300 mymap contains: a => 1101 b => 2202 ----------------------------------------------------------------------------------------- // map::emplace #include <iostream> #include <map> int main () { std::map<char,int> mymap; mymap.emplace('x',100); mymap.emplace('y',200); mymap.emplace('z',100); std::cout << "mymap contains:"; for (auto& x: mymap) std::cout << " [" << x.first << ':' << x.second << ']'; std::cout << '\n'; return 0; } Output: mymap contains: [x:100] [y:200] [z:100] ----------------------------------------------------------------------------------------- // map::emplace_hint #include <iostream> #include <map> int main () { std::map<char,int> mymap; auto it = mymap.end(); it = mymap.emplace_hint(it,'b',10); mymap.emplace_hint(it,'a',12); mymap.emplace_hint(mymap.end(),'c',14); std::cout << "mymap contains:"; for (auto& x: mymap) std::cout << " [" << x.first << ':' << x.second << ']'; std::cout << '\n'; return 0; } Output: mymap contains: [a:12] [b:10] [c:14]
- Observers
函数 | 函数原型 | 功能描述 |
key_comp | key_compare key_comp() const; | Returns a copy of the comparison object used by the container to compare keys. |
value_comp | value_compare value_comp() const; | Returns a comparison object that can be used to compare two elements to get whether the key of the first one goes before the second.The arguments taken by this function object are of member type value_type (defined in map as an alias of pair<const key_type,mapped_type>), but the mapped_type part of the value is not taken into consideration in this comparison. |
示例代码:
// map::key_comp #include <iostream> #include <map> int main () { std::map<char,int> mymap; std::map<char,int>::key_compare mycomp = mymap.key_comp(); mymap['a']=100; mymap['b']=200; mymap['c']=300; std::cout << "mymap contains:\n"; char highest = mymap.rbegin()->first; // key value of last element std::map<char,int>::iterator it = mymap.begin(); do { std::cout << it->first << " => " << it->second << '\n'; } while ( mycomp((*it++).first, highest) ); std::cout << '\n'; return 0; } Output: mymap contains: a => 100 b => 200 c => 300 ---------------------------------------------------------------------------------------- // map::value_comp #include <iostream> #include <map> int main () { std::map<char,int> mymap; mymap['x']=1001; mymap['y']=2002; mymap['z']=3003; std::cout << "mymap contains:\n"; std::pair<char,int> highest = *mymap.rbegin(); // last element std::map<char,int>::iterator it = mymap.begin(); do { std::cout << it->first << " => " << it->second << '\n'; } while ( mymap.value_comp()(*it++, highest) ); return 0; } Output: mymap contains: x => 1001 y => 2002 z => 3003
- 其他操作(Operations)
函数 | 函数原型 | 功能描述 |
find | iterator find (const key_type& k); | Get iterator to element |
const_iterator find (const key_type& k) const; | ||
count | size_type count (const key_type& k) const; | Count elements with a specific key, 0 or 1 |
lower_bound | iterator lower_bound (const key_type& k); | Returns an iterator pointing to the first element in the container whose key is not considered to go before k (i.e., either it is equivalent or goes after). |
const_iterator lower_bound (const key_type& k) const; | ||
upper_bound | iterator upper_bound (const key_type& k); | Returns an iterator pointing to the first element in the container whose key is considered to go after k. |
const_iterator upper_bound (const key_type& k) const; | ||
equal_range | pair<const_iterator,const_iterator> equal_range (const key_type& k) const; | Returns the bounds of a range that includes all the elements in the container which have a key equivalent to k. Because the elements in a map container have unique keys, the range returned will contain a single element at most. |
pair<iterator,iterator> equal_range (const key_type& k); |
示例代码:
// map::find #include <iostream> #include <map> int main () { std::map<char,int> mymap; std::map<char,int>::iterator it; mymap['a']=50; mymap['b']=100; mymap['c']=150; mymap['d']=200; it = mymap.find('b'); if (it != mymap.end()) mymap.erase (it); // print content: std::cout << "elements in mymap:" << '\n'; std::cout << "a => " << mymap.find('a')->second << '\n'; std::cout << "c => " << mymap.find('c')->second << '\n'; std::cout << "d => " << mymap.find('d')->second << '\n'; return 0; } Output: elements in mymap: a => 50 c => 150 d => 200 ----------------------------------------------------------------------------- // map::count #include <iostream> #include <map> int main () { std::map<char,int> mymap; char c; mymap ['a']=101; mymap ['c']=202; mymap ['f']=303; for (c='a'; c<'h'; c++) { std::cout << c; if (mymap.count(c)>0) std::cout << " is an element of mymap.\n"; else std::cout << " is not an element of mymap.\n"; } return 0; } Output: a is an element of mymap. b is not an element of mymap. c is an element of mymap. d is not an element of mymap. e is not an element of mymap. f is an element of mymap. g is not an element of mymap. ----------------------------------------------------------------------------- // map::lower_bound/upper_bound #include <iostream> #include <map> int main () { std::map<char,int> mymap; std::map<char,int>::iterator itlow,itup; mymap['a']=20; mymap['b']=40; mymap['c']=60; mymap['d']=80; mymap['e']=100; itlow=mymap.lower_bound ('b'); // itlow points to b itup=mymap.upper_bound ('d'); // itup points to e (not d!) mymap.erase(itlow,itup); // erases [itlow,itup) // print content: for (std::map<char,int>::iterator it=mymap.begin(); it!=mymap.end(); ++it) std::cout << it->first << " => " << it->second << '\n'; return 0; } Output: a => 20 e => 100 ----------------------------------------------------------------------------- // map::equal_range #include <iostream> #include <map> int main () { std::map<char,int> mymap; mymap['a']=10; mymap['b']=20; mymap['c']=30; std::pair<std::map<char,int>::iterator,std::map<char,int>::iterator> ret; ret = mymap.equal_range('b'); std::cout << "lower bound points to: "; std::cout << ret.first->first << " => " << ret.first->second << '\n'; std::cout << "upper bound points to: "; std::cout << ret.second->first << " => " << ret.second->second << '\n'; return 0; } Output: lower bound points to: 'b' => 20 upper bound points to: 'c' => 30
- 分配器(Allocator)
函数 | 函数原型 | 功能描述 |
get_allocator | allocator_type get_allocator() const noexcept; | Get allocator |
翻译、参考:
http://www.cplusplus.com/reference/map/map/